[Qemu-devel] [v7][PATCH 05/10] xen, gfx passthrough: basic graphics passthrough support
basic gfx passthrough support: - add a vga type for gfx passthrough - register/unregister legacy VGA I/O ports and MMIOs for passthrough GFX Signed-off-by: Tiejun Chen tiejun.c...@intel.com Signed-off-by: Yang Zhang yang.z.zh...@intel.com --- hw/core/machine.c| 20 hw/xen/Makefile.objs | 1 + hw/xen/xen-host-pci-device.c | 5 ++ hw/xen/xen-host-pci-device.h | 1 + hw/xen/xen_pt.c | 4 ++ hw/xen/xen_pt.h | 10 +++- hw/xen/xen_pt_graphics.c | 111 +++ include/hw/boards.h | 1 + qemu-options.hx | 3 ++ vl.c | 10 10 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 hw/xen/xen_pt_graphics.c diff --git a/hw/core/machine.c b/hw/core/machine.c index cb1185a..6ac3ee4 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -225,6 +225,20 @@ static void machine_set_usb(Object *obj, bool value, Error **errp) ms-usb = value; } +static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp) +{ +MachineState *ms = MACHINE(obj); + +return ms-igd_gfx_passthru; +} + +static void machine_set_igd_gfx_passthru(Object *obj, bool value, Error **errp) +{ +MachineState *ms = MACHINE(obj); + +ms-igd_gfx_passthru = value; +} + static char *machine_get_firmware(Object *obj, Error **errp) { MachineState *ms = MACHINE(obj); @@ -379,6 +393,12 @@ static void machine_initfn(Object *obj) object_property_set_description(obj, usb, Set on/off to enable/disable usb, NULL); +object_property_add_bool(obj, igd-passthru, + machine_get_igd_gfx_passthru, + machine_set_igd_gfx_passthru, NULL); +object_property_set_description(obj, igd-passthru, +Set on/off to enable/disable igd passthrou, +NULL); object_property_add_str(obj, firmware, machine_get_firmware, machine_set_firmware, NULL); diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs index a0ca0aa..a9ad7e7 100644 --- a/hw/xen/Makefile.objs +++ b/hw/xen/Makefile.objs @@ -3,3 +3,4 @@ common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o +obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o xen_pt_graphics.o diff --git a/hw/xen/xen-host-pci-device.c b/hw/xen/xen-host-pci-device.c index 743b37b..a54b7de 100644 --- a/hw/xen/xen-host-pci-device.c +++ b/hw/xen/xen-host-pci-device.c @@ -376,6 +376,11 @@ int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain, goto error; } d-irq = v; +rc = xen_host_pci_get_hex_value(d, class, v); +if (rc) { +goto error; +} +d-class_code = v; d-is_virtfn = xen_host_pci_dev_is_virtfn(d); return 0; diff --git a/hw/xen/xen-host-pci-device.h b/hw/xen/xen-host-pci-device.h index c2486f0..f1e1c30 100644 --- a/hw/xen/xen-host-pci-device.h +++ b/hw/xen/xen-host-pci-device.h @@ -25,6 +25,7 @@ typedef struct XenHostPCIDevice { uint16_t vendor_id; uint16_t device_id; +uint32_t class_code; int irq; XenHostPCIIORegion io_regions[PCI_NUM_REGIONS - 1]; diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index f2893b2..1d78021 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -450,6 +450,7 @@ static int xen_pt_register_regions(XenPCIPassthroughState *s) d-rom.size, d-rom.base_addr); } +xen_pt_register_vga_regions(d); return 0; } @@ -748,6 +749,7 @@ out: static void xen_pt_unregister_device(PCIDevice *d) { XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d); +XenHostPCIDevice *host_dev = s-real_device; uint8_t machine_irq = s-machine_irq; uint8_t intx = xen_pt_pci_intx(s); int rc; @@ -791,6 +793,8 @@ static void xen_pt_unregister_device(PCIDevice *d) /* delete all emulated config registers */ xen_pt_config_delete(s); +xen_pt_unregister_vga_regions(host_dev); + memory_listener_unregister(s-memory_listener); memory_listener_unregister(s-io_listener); diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h index 942dc60..3325387 100644 --- a/hw/xen/xen_pt.h +++ b/hw/xen/xen_pt.h @@ -298,5 +298,13 @@ static inline bool xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar) return s-msix s-msix-bar_index == bar; } - +extern bool has_igd_gfx_passthru; +static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev) +{ +return (has_igd_gfx_passthru + ((dev-class_code 0x8) == PCI_CLASS_DISPLAY_VGA)); +} +int xen_pt_register_vga_regions(XenHostPCIDevice *dev); +int
[Qemu-devel] [PATCH V4 11/19] virtio-s390: switch to bus specific queue limit
Instead of depending on marco, switch to use a bus specific queue limit. Cc: Alexander Graf ag...@suse.de Cc: Richard Henderson r...@twiddle.net Cc: Christian Borntraeger borntrae...@de.ibm.com Cc: Cornelia Huck cornelia.h...@de.ibm.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/s390x/s390-virtio-bus.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 2b41e32..9d6028d 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -45,6 +45,8 @@ do { } while (0) #endif +#define VIRTIO_S390_QUEUE_MAX 64 + static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size, VirtIOS390Device *dev); @@ -344,7 +346,7 @@ static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev) VirtIODevice *vdev = dev-vdev; int num_vq; -for (num_vq = 0; num_vq VIRTIO_PCI_QUEUE_MAX; num_vq++) { +for (num_vq = 0; num_vq virtio_get_queue_max(vdev); num_vq++) { if (!virtio_queue_get_num(vdev, num_vq)) { break; } @@ -446,7 +448,7 @@ VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus, QTAILQ_FOREACH(kid, bus-bus.children, sibling) { VirtIOS390Device *dev = (VirtIOS390Device *)kid-child; -for(i = 0; i VIRTIO_PCI_QUEUE_MAX; i++) { +for (i = 0; i virtio_get_queue_max(dev-vdev); i++) { if (!virtio_queue_get_addr(dev-vdev, i)) break; if (virtio_queue_get_addr(dev-vdev, i) == mem) { @@ -715,7 +717,7 @@ static void virtio_s390_bus_class_init(ObjectClass *klass, void *data) bus_class-max_dev = 1; k-notify = virtio_s390_notify; k-get_features = virtio_s390_get_features; -k-queue_max = VIRTIO_PCI_QUEUE_MAX; +k-queue_max = VIRTIO_S390_QUEUE_MAX; } static const TypeInfo virtio_s390_bus_info = { -- 2.1.0
Re: [Qemu-devel] [PATCH] MAINTAINERS: Add myself as the maintainer of the Quorum driver
On Tue, Mar 17, 2015 at 05:23:56PM +, Stefan Hajnoczi wrote: + +Quorum +M: Alberto Garcia be...@igalia.com +S: Supported +F: block/quorum.c I'd like to also add the qemu-bl...@nongnu.org mailing list to your MAINTAINERS stanza because patches should be CCed to the block list: L: qemu-bl...@nongnu.org Does that sound good? If you have any questions, just let me know. Yes, please go ahead. Thanks, Berto
[Qemu-devel] [PATCH V4 03/19] ppc: spapr: add 2.4 machine type
The following patches will limit the following things to legacy machine type: - maximum number of virtqueues for virtio-pci were limited to 64 - auto msix bar size for virtio-net-pci were disabled by default Cc: Alexander Graf ag...@suse.de Cc: qemu-...@nongnu.org Signed-off-by: Jason Wang jasow...@redhat.com --- hw/ppc/spapr.c | 31 +-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 7fb174f..22f4ae4 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1803,8 +1803,13 @@ static const TypeInfo spapr_machine_info = { #define SPAPR_COMPAT_2_1 \ SPAPR_COMPAT_2_2 +static void spapr_compat_2_3(Object *obj) +{ +} + static void spapr_compat_2_2(Object *obj) { +spapr_compat_2_3(obj); } static void spapr_compat_2_1(Object *obj) @@ -1812,6 +1817,12 @@ static void spapr_compat_2_1(Object *obj) spapr_compat_2_2(obj); } +static void spapr_machine_2_3_instance_init(Object *obj) +{ +spapr_compat_2_3(obj); +spapr_machine_initfn(obj); +} + static void spapr_machine_2_2_instance_init(Object *obj) { spapr_compat_2_2(obj); @@ -1871,14 +1882,29 @@ static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data) mc-name = pseries-2.3; mc-desc = pSeries Logical Partition (PAPR compliant) v2.3; -mc-alias = pseries; -mc-is_default = 1; } static const TypeInfo spapr_machine_2_3_info = { .name = TYPE_SPAPR_MACHINE 2.3, .parent= TYPE_SPAPR_MACHINE, .class_init= spapr_machine_2_3_class_init, +.instance_init = spapr_machine_2_3_instance_init, +}; + +static void spapr_machine_2_4_class_init(ObjectClass *oc, void *data) +{ +MachineClass *mc = MACHINE_CLASS(oc); + +mc-name = pseries-2.4; +mc-desc = pSeries Logical Partition (PAPR compliant) v2.4; +mc-alias = pseries; +mc-is_default = 1; +} + +static const TypeInfo spapr_machine_2_4_info = { +.name = TYPE_SPAPR_MACHINE 2.4, +.parent= TYPE_SPAPR_MACHINE, +.class_init= spapr_machine_2_4_class_init, }; static void spapr_machine_register_types(void) @@ -1887,6 +1913,7 @@ static void spapr_machine_register_types(void) type_register_static(spapr_machine_2_1_info); type_register_static(spapr_machine_2_2_info); type_register_static(spapr_machine_2_3_info); +type_register_static(spapr_machine_2_4_info); } type_init(spapr_machine_register_types) -- 2.1.0
[Qemu-devel] [PATCH V4 08/19] virtio-net: fix the upper bound when trying to delete queues
Virtqueue were indexed from zero, so don't delete virtqueue whose index is n-max_queues * 2 + 1. Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/net/virtio-net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 59f76bc..b6fac9c 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1309,7 +1309,7 @@ static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue) n-multiqueue = multiqueue; -for (i = 2; i = n-max_queues * 2 + 1; i++) { +for (i = 2; i n-max_queues * 2 + 1; i++) { virtio_del_queue(vdev, i); } -- 2.1.0
Re: [Qemu-devel] RFC: -object vs -chardev creation order
On Wed, Mar 18, 2015 at 10:43:25AM +0100, Markus Armbruster wrote: Daniel P. Berrange berra...@redhat.com writes: A third option is to not process -object args in one go, instead process each type of object at a time. eg we'd first create all the -object tls-credential instances, then create the -chardev instances, then create the -object rng-egd instances. This is probably the least amount of work in short term, but not all that scalable, unless we do a catch-all default case, so we only need code up hacks for a few particular object types. Thus my gut feeling is to do option 3, but I'd like other opinions before embarking on this Piling yet another hack on top isn't great, put telling you no more hacks after everybody and his dog already got to pile on some doesn't feel fair. I think I'll do this right now, since it should be a fast fix. That said: can we sort the creation work topologically? Requires identifying references. In the QemuOpts world, a reference is a string-valued parameter that is interpreted as ID in a well-known QemuOptsList. Adding the necessary information to QemuOptDesc desc[] shouldn't be too hard. The ones with empty desc[] could be troublesome, as usual. This sounds intriguing though - we should have enough info around to do a topological sort - its a shame that properties are only registered at time the object is created, rather than being registered against the classes, as then we wouldn't even need to add more info to the QemuOptsList. I'll have a think about this approach though and see if I can come up with something that works Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
Re: [Qemu-devel] [PATCH for-2.3] numa: pc: fix default VCPU to node mapping
On Tue, 17 Mar 2015 17:59:48 +0100 Andreas Färber afaer...@suse.de wrote: Am 17.03.2015 um 17:42 schrieb Eduardo Habkost: On Tue, Mar 17, 2015 at 03:48:38PM +, Igor Mammedov wrote: since commit dd0247e0 pc: acpi: mark all possible CPUs as enabled in SRAT Linux kernel actually tries to use CPU to Node mapping from QEMU provided SRAT table instead of discarding it, and that in some cases breaks build_sched_domains() which expects sane mapping where cores/threads belonging to the same socket are on the same NUMA node. With current default round-robin mapping of VCPUs to nodes guest ends-up with cores/threads belonging to the same socket being on different NUMA nodes. For example with following CLI: qemu-kvm -m 4G -smp 5,sockets=1,cores=4,threads=1,maxcpus=8 \ -numa node,nodeid=0 -numa node,nodeid=1 2.6.32 based kernels will hang on boot due to incorrectly build sched_group-s list in update_sd_lb_stats() so comment in QEMU justifying dumb default mapping: guest OSes must cope with this anyway, because there are BIOSes out there in real machines which also use this scheme. isn't really valid. Replacing default mapping withi a manual, where VCPUs belonging to the same socket are on the same NUMA node, fixes issue for guests which can't handle nonsense topology i.e. cnaging CLI to: -numa node,nodeid=0,cpus=0-3 -numa node,nodeid=1,cpus=4-7 So instead of simply scattering VCPUs around nodes, map the same socket VCPUs to the same NUMA node, which is what guest would expect from a sane hardware/BIOS. Signed-off-by: Igor Mammedov imamm...@redhat.com I believe the proposed behavior is much better. But if we are going to break compatibility, shouldn't we at least do that before the first -rc so we get feedback in case it break existing configurations? About qemu_cpu_socket_id_from_index(): all qemu-system-* binaries have smp_cores and smp_threads available (even if machines ignore it), but the default stub can return values that are larger than the number of sockets if smp_cores*smp_threads 1, which would be obviously incorrect. Isn't it easier to simply make cpu_index/(smp_cores*smp_sockets) be the default cpu_index-socket mapping function, and allow machine-specific (not arch-specific) overrides if necessary? Agree that the proposed stub solution is not so nice. Can you propose a MachineClass based solution instead? sure The example I keep bringing up for x86 is that the Galileo boards or even the Minnow boards don't really have sockets, being a SoC. Thanks, Andreas
[Qemu-devel] [PULL 05/19] nbd: Pass return value from nbd_handle_list()
From: Max Reitz mre...@redhat.com While it does not make a difference in practice, nbd_receive_options() generally returns -errno, so it should do that here as well; and the easiest way to achieve this is by passing on the value returned by nbd_handle_list(). Signed-off-by: Max Reitz mre...@redhat.com Message-Id: 1424887718-10800-7-git-send-email-mre...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- nbd.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nbd.c b/nbd.c index 02ba0fe..34f4dbb 100644 --- a/nbd.c +++ b/nbd.c @@ -351,7 +351,7 @@ fail: static int nbd_receive_options(NBDClient *client) { while (1) { -int csock = client-sock; +int csock = client-sock, ret; uint32_t tmp, length; uint64_t magic; @@ -398,8 +398,9 @@ static int nbd_receive_options(NBDClient *client) TRACE(Checking option); switch (be32_to_cpu(tmp)) { case NBD_OPT_LIST: -if (nbd_handle_list(client, length) 0) { -return 1; +ret = nbd_handle_list(client, length); +if (ret 0) { +return ret; } break; -- 2.3.0
[Qemu-devel] [PULL 18/19] virtio-scsi-dataplane: fix memory leak in virtio_scsi_vring_init
From: Bo Su su...@huawei.com if k-set_host_notifier failed, VirtIOSCSIVring *r will leak Signed-off-by: Bo Su su...@huawei.com Message-Id: 1426671732-80213-1-git-send-email-su...@huawei.com Reviewed-by: Fam Zheng f...@redhat.com Reviewed-by: Gonglei arei.gong...@huawei.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/scsi/virtio-scsi-dataplane.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 3f40ff0..c069cd7 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -45,7 +45,7 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s, { BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s))); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -VirtIOSCSIVring *r = g_slice_new(VirtIOSCSIVring); +VirtIOSCSIVring *r; int rc; /* Set up virtqueue notify */ @@ -56,6 +56,8 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s, s-dataplane_fenced = true; return NULL; } + +r = g_slice_new(VirtIOSCSIVring); r-host_notifier = *virtio_queue_get_host_notifier(vq); r-guest_notifier = *virtio_queue_get_guest_notifier(vq); aio_set_event_notifier(s-ctx, r-host_notifier, handler); -- 2.3.0
[Qemu-devel] [v7][PATCH 03/10] piix: create host bridge to passthrough
Implement a pci host bridge specific to passthrough. Actually this just inherits the standard one. And we also just expose a minimal real host bridge pci configuration subset. Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- hw/pci-host/piix.c | 82 include/hw/i386/pc.h | 2 ++ 2 files changed, 84 insertions(+) diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index c812eaa..0906ba5 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -728,6 +728,87 @@ static const TypeInfo i440fx_info = { .class_init= i440fx_class_init, }; +/* IGD Passthrough Host Bridge. */ +typedef struct { +uint8_t offset; +uint8_t len; +} IGDHostInfo; + +/* Here we just expose minimal host bridge offset subset. */ +static const IGDHostInfo igd_host_bridge_infos[] = { +{0x08, 2}, /* revision id */ +{0x2c, 2}, /* sybsystem vendor id */ +{0x2e, 2}, /* sybsystem id */ +{0x50, 2}, /* SNB: processor graphics control register */ +{0x52, 2}, /* processor graphics control register */ +{0xa4, 4}, /* SNB: graphics base of stolen memory */ +{0xa8, 4}, /* SNB: base of GTT stolen memory */ +}; + +static int host_pci_config_read(int pos, int len, uint32_t val) +{ +char path[PATH_MAX]; +int config_fd; +ssize_t size = sizeof(path); +/* Access real host bridge. */ +int rc = snprintf(path, size, /sys/bus/pci/devices/%04x:%02x:%02x.%d/%s, + 0, 0, 0, 0, config); + +if (rc = size || rc 0) { +return -ENODEV; +} + +config_fd = open(path, O_RDWR); +if (config_fd 0) { +return -ENODEV; +} + +do { +rc = pread(config_fd, (uint8_t *)val, len, pos); +} while (rc 0 (errno == EINTR || errno == EAGAIN)); +if (rc != len) { +return -errno; +} + +return 0; +} + +static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev) +{ +uint32_t val = 0; +int rc, i, num; +int pos, len; + +num = ARRAY_SIZE(igd_host_bridge_infos); +for (i = 0; i num; i++) { +pos = igd_host_bridge_infos[i].offset; +len = igd_host_bridge_infos[i].len; +rc = host_pci_config_read(pos, len, val); +if (rc) { +return -ENODEV; +} +pci_default_write_config(pci_dev, pos, val, len); +} + +return 0; +} + +static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + +k-init = igd_pt_i440fx_initfn; +dc-desc = IGD Passthrough Host bridge; +} + +static const TypeInfo igd_passthrough_i440fx_info = { +.name = TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE, +.parent= TYPE_I440FX_PCI_DEVICE, +.instance_size = sizeof(PCII440FXState), +.class_init= igd_passthrough_i440fx_class_init, +}; + static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge, PCIBus *rootbus) { @@ -769,6 +850,7 @@ static const TypeInfo i440fx_pcihost_info = { static void i440fx_register_types(void) { type_register_static(i440fx_info); +type_register_static(igd_passthrough_i440fx_info); type_register_static(piix3_info); type_register_static(piix3_xen_info); type_register_static(i440fx_pcihost_info); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 99dc26b..ec3ca88 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -233,6 +233,8 @@ typedef struct PCII440FXState PCII440FXState; #define TYPE_I440FX_PCI_HOST_BRIDGE i440FX-pcihost #define TYPE_I440FX_PCI_DEVICE i440FX +#define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE xen-igd-passthrough-i440FX + PCIBus *i440fx_init(const char *host_type, const char *pci_type, PCII440FXState **pi440fx_state, int *piix_devfn, ISABus **isa_bus, qemu_irq *pic, -- 1.9.1
[Qemu-devel] [v7][PATCH 08/10] xen, gfx passthrough: register a isa bridge
Currently we just register this isa bridge when we use IGD passthrough in Xen side. Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- hw/xen/xen_pt.c | 18 ++ include/hw/xen/xen.h | 1 + 2 files changed, 19 insertions(+) diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index fcc9f1c..2d5cebb 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -632,6 +632,21 @@ static const MemoryListener xen_pt_io_listener = { .priority = 10, }; +static void +xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s, + XenHostPCIDevice *dev) +{ +uint16_t gpu_dev_id; +PCIDevice *d = s-dev; + +if (!is_igd_vga_passthrough(dev)) { +return; +} + +gpu_dev_id = dev-device_id; +igd_passthrough_isa_bridge_create(d-bus, gpu_dev_id); +} + /* init */ static int xen_pt_initfn(PCIDevice *d) @@ -680,6 +695,9 @@ static int xen_pt_initfn(PCIDevice *d) xen_host_pci_device_put(s-real_device); return -1; } + +/* Register ISA bridge for passthrough GFX. */ +xen_igd_passthrough_isa_bridge_create(s, s-real_device); } /* Handle real device's MMIO/PIO BARs */ diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index 4356af4..703148e 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -51,4 +51,5 @@ void xen_register_framebuffer(struct MemoryRegion *mr); # define HVM_MAX_VCPUS 32 #endif +extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id); #endif /* QEMU_HW_XEN_H */ -- 1.9.1
[Qemu-devel] [v7][PATCH 07/10] igd gfx passthrough: create a isa bridge
Currently IGD drivers always need to access PCH by 1f.0. But we don't want to poke that directly to get ID, and although in real world different GPU should have different PCH. But actually the different PCH DIDs likely map to different PCH SKUs. We do the same thing for the GPU. For PCH, the different SKUs are going to be all the same silicon design and implementation, just different features turn on and off with fuses. The SW interfaces should be consistent across all SKUs in a given family (eg LPT). But just same features may not be supported. Most of these different PCH features probably don't matter to the Gfx driver, but obviously any difference in display port connections will so it should be fine with any PCH in case of passthrough. So currently use one PCH version, 0x8c4e, to cover all HSW(Haswell) scenarios, 0x9cc3 for BDW(Broadwell). Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- hw/i386/pc_piix.c | 113 ++ 1 file changed, 113 insertions(+) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index cea3a5c..8fbfc09 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -956,6 +956,119 @@ static QEMUMachine pc_machine_v0_10 = { .hw_version = 0.10, }; +typedef struct { +uint16_t gpu_device_id; +uint16_t pch_device_id; +uint8_t pch_revision_id; +} IGDDeviceIDInfo; + +/* In real world different GPU should have different PCH. But actually + * the different PCH DIDs likely map to different PCH SKUs. We do the + * same thing for the GPU. For PCH, the different SKUs are going to be + * all the same silicon design and implementation, just different + * features turn on and off with fuses. The SW interfaces should be + * consistent across all SKUs in a given family (eg LPT). But just same + * features may not be supported. + * + * Most of these different PCH features probably don't matter to the + * Gfx driver, but obviously any difference in display port connections + * will so it should be fine with any PCH in case of passthrough. + * + * So currently use one PCH version, 0x8c4e, to cover all HSW(Haswell) + * scenarios, 0x9cc3 for BDW(Broadwell). + */ +static const IGDDeviceIDInfo igd_combo_id_infos[] = { +/* HSW Classic */ +{0x0402, 0x8c4e, 0x04}, /* HSWGT1D, HSWD_w7 */ +{0x0406, 0x8c4e, 0x04}, /* HSWGT1M, HSWM_w7 */ +{0x0412, 0x8c4e, 0x04}, /* HSWGT2D, HSWD_w7 */ +{0x0416, 0x8c4e, 0x04}, /* HSWGT2M, HSWM_w7 */ +{0x041E, 0x8c4e, 0x04}, /* HSWGT15D, HSWD_w7 */ +/* HSW ULT */ +{0x0A06, 0x8c4e, 0x04}, /* HSWGT1UT, HSWM_w7 */ +{0x0A16, 0x8c4e, 0x04}, /* HSWGT2UT, HSWM_w7 */ +{0x0A26, 0x8c4e, 0x06}, /* HSWGT3UT, HSWM_w7 */ +{0x0A2E, 0x8c4e, 0x04}, /* HSWGT3UT28W, HSWM_w7 */ +{0x0A1E, 0x8c4e, 0x04}, /* HSWGT2UX, HSWM_w7 */ +{0x0A0E, 0x8c4e, 0x04}, /* HSWGT1ULX, HSWM_w7 */ +/* HSW CRW */ +{0x0D26, 0x8c4e, 0x04}, /* HSWGT3CW, HSWM_w7 */ +{0x0D22, 0x8c4e, 0x04}, /* HSWGT3CWDT, HSWD_w7 */ +/* HSW Server */ +{0x041A, 0x8c4e, 0x04}, /* HSWSVGT2, HSWD_w7 */ +/* HSW SRVR */ +{0x040A, 0x8c4e, 0x04}, /* HSWSVGT1, HSWD_w7 */ +/* BSW */ +{0x1606, 0x9cc3, 0x03}, /* BDWULTGT1, BDWM_w7 */ +{0x1616, 0x9cc3, 0x03}, /* BDWULTGT2, BDWM_w7 */ +{0x1626, 0x9cc3, 0x03}, /* BDWULTGT3, BDWM_w7 */ +{0x160E, 0x9cc3, 0x03}, /* BDWULXGT1, BDWM_w7 */ +{0x161E, 0x9cc3, 0x03}, /* BDWULXGT2, BDWM_w7 */ +{0x1602, 0x9cc3, 0x03}, /* BDWHALOGT1, BDWM_w7 */ +{0x1612, 0x9cc3, 0x03}, /* BDWHALOGT2, BDWM_w7 */ +{0x1622, 0x9cc3, 0x03}, /* BDWHALOGT3, BDWM_w7 */ +{0x162B, 0x9cc3, 0x03}, /* BDWHALO28W, BDWM_w7 */ +{0x162A, 0x9cc3, 0x03}, /* BDWGT3WRKS, BDWM_w7 */ +{0x162D, 0x9cc3, 0x03}, /* BDWGT3SRVR, BDWM_w7 */ +}; + +static void isa_bridge_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + +dc-desc= ISA bridge faked to support IGD PT; +k-vendor_id= PCI_VENDOR_ID_INTEL; +k-class_id = PCI_CLASS_BRIDGE_ISA; +}; + +static TypeInfo isa_bridge_info = { +.name = igd-passthrough-isa-bridge, +.parent= TYPE_PCI_DEVICE, +.instance_size = sizeof(PCIDevice), +.class_init = isa_bridge_class_init, +}; + +static void pt_graphics_register_types(void) +{ +type_register_static(isa_bridge_info); +} +type_init(pt_graphics_register_types) + +void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id) +{ +struct PCIDevice *bridge_dev; +int i, num; +uint16_t pch_dev_id = 0x; +uint8_t pch_rev_id; + +num = ARRAY_SIZE(igd_combo_id_infos); +for (i = 0; i num; i++) { +if (gpu_dev_id == igd_combo_id_infos[i].gpu_device_id) { +pch_dev_id = igd_combo_id_infos[i].pch_device_id; +pch_rev_id = igd_combo_id_infos[i].pch_revision_id; +} +} + +if (pch_dev_id == 0x) { +return; +} + +/* Currently IGD drivers always
Re: [Qemu-devel] RFC: -object vs -chardev creation order
Daniel P. Berrange berra...@redhat.com writes: The current QEMU startup code will create -chardev backends first, then create -object backends, then -fsdev backends and so on, in some pretty arbitrary order of types. There is already a dependancy from the rng-egd object type, which has a link to a chardev, which requires -chardev options be processed before -object options. In my work to introduce an object type for TLS credentials though, we encounter exactly the opposite dependancy. A -chardev option will require that -object options be processed first, so that the TLS credantials can be created. This is a no-win situation. Both orders of creation are wrong for some set of use cases. This is only going to get worse over time, as more types of user creatable objects are defined. The application invoking QEMU could easily solve it, by putting the args on the command line in the order in which they need to processed, but then QEMU throws away this ordering information and creates them based on type of backend. Yes, and that's stupid. I'm unclear on whether anyone has thought about ways to solve this yet, but it is a blocker for my work now, so I need to figure out some kind of solution asap, even if only a temporary workaround. One option is to convert the -chardev backends so they become user creatable objects, and thus -object can obsolete use of -chardev for these. This sounds simple, but I fear it could be a rather large yak shaving exercise to get that done. Another idea is to perhaps change the way options are stored, so that instead of having a separate QemuOptsList for each type of option, have one single list and store the type with each entry in the list. Then we can iterate over the single list creating things in exactly the same order that they were passed on the command line. It's how we should've done it, but: I fear this may cause regressions for apps using QEMU though - eg if some app is placing '-object rng-egd' in the args, before the -chardev it would currently work, but if we switch to honour ordering it would fail. We could introduce a flag -strict-ordering but that feels gross in itself. Yes. I'm afraid we'll have to break our byzantine command line at some point... I'd rather not break it now, though. A third option is to not process -object args in one go, instead process each type of object at a time. eg we'd first create all the -object tls-credential instances, then create the -chardev instances, then create the -object rng-egd instances. This is probably the least amount of work in short term, but not all that scalable, unless we do a catch-all default case, so we only need code up hacks for a few particular object types. Thus my gut feeling is to do option 3, but I'd like other opinions before embarking on this Piling yet another hack on top isn't great, put telling you no more hacks after everybody and his dog already got to pile on some doesn't feel fair. That said: can we sort the creation work topologically? Requires identifying references. In the QemuOpts world, a reference is a string-valued parameter that is interpreted as ID in a well-known QemuOptsList. Adding the necessary information to QemuOptDesc desc[] shouldn't be too hard. The ones with empty desc[] could be troublesome, as usual.
[Qemu-devel] [PATCH V4 10/19] virtio-ccw: introduce ccw specific queue limit
Instead of depending on marco, using a bus specific limit. Cc: Alexander Graf ag...@suse.de Cc: Cornelia Huck cornelia.h...@de.ibm.com Cc: Christian Borntraeger borntrae...@de.ibm.com Cc: Richard Henderson r...@twiddle.net Signed-off-by: Jason Wang jasow...@redhat.com --- hw/s390x/s390-virtio-ccw.c | 7 +-- hw/s390x/virtio-ccw.c| 19 --- include/hw/s390x/s390_flic.h | 4 +++- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index afb539a..96b84ab 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -55,6 +55,7 @@ void io_subsystem_reset(void) static int virtio_ccw_hcall_notify(const uint64_t *args) { +VirtIODevice *vdev; uint64_t subch_id = args[0]; uint64_t queue = args[1]; SubchDev *sch; @@ -67,10 +68,12 @@ static int virtio_ccw_hcall_notify(const uint64_t *args) if (!sch || !css_subch_visible(sch)) { return -EINVAL; } -if (queue = VIRTIO_PCI_QUEUE_MAX) { + +vdev = virtio_ccw_get_vdev(sch); +if (queue = virtio_get_queue_max(vdev)) { return -EINVAL; } -virtio_queue_notify(virtio_ccw_get_vdev(sch), queue); +virtio_queue_notify(vdev, queue); return 0; } diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index dfe6ded..935b880 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -32,6 +32,8 @@ static QTAILQ_HEAD(, IndAddr) indicator_addresses = QTAILQ_HEAD_INITIALIZER(indicator_addresses); +#define VIRTIO_CCW_QUEUE_MAX ADAPTER_ROUTES_MAX_GSI + static IndAddr *get_indicator(hwaddr ind_addr, int len) { IndAddr *indicator; @@ -170,7 +172,7 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev) return; } vdev = virtio_bus_get_device(dev-bus); -for (n = 0; n VIRTIO_PCI_QUEUE_MAX; n++) { +for (n = 0; n virtio_get_queue_max(vdev); n++) { if (!virtio_queue_get_num(vdev, n)) { continue; } @@ -205,7 +207,7 @@ static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev) return; } vdev = virtio_bus_get_device(dev-bus); -for (n = 0; n VIRTIO_PCI_QUEUE_MAX; n++) { +for (n = 0; n virtio_get_queue_max(vdev); n++) { if (!virtio_queue_get_num(vdev, n)) { continue; } @@ -265,8 +267,9 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, uint16_t index, uint16_t num) { VirtIODevice *vdev = virtio_ccw_get_vdev(sch); +int queue_max = virtio_get_queue_max(vdev); -if (index VIRTIO_PCI_QUEUE_MAX) { +if (index queue_max) { return -EINVAL; } @@ -291,7 +294,7 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, virtio_queue_set_vector(vdev, index, index); } /* tell notify handler in case of config change */ -vdev-config_vector = VIRTIO_PCI_QUEUE_MAX; +vdev-config_vector = queue_max; return 0; } @@ -1036,14 +1039,16 @@ static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc, static void virtio_ccw_notify(DeviceState *d, uint16_t vector) { VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d); +VirtIODevice *vdev = virtio_bus_get_device(dev-bus); SubchDev *sch = dev-sch; uint64_t indicators; -if (vector = 128) { +/* queue indicators + secondary indicators */ +if (vector = virtio_get_queue_max(vdev) + 64) { return; } -if (vector VIRTIO_PCI_QUEUE_MAX) { +if (vector virtio_get_queue_max(vdev)) { if (!dev-indicators) { return; } @@ -1711,7 +1716,7 @@ static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data) k-load_queue = virtio_ccw_load_queue; k-save_config = virtio_ccw_save_config; k-load_config = virtio_ccw_load_config; -k-queue_max = VIRTIO_PCI_QUEUE_MAX; +k-queue_max = VIRTIO_CCW_QUEUE_MAX; } static const TypeInfo virtio_ccw_bus_info = { diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h index 489d73b..e1b0389 100644 --- a/include/hw/s390x/s390_flic.h +++ b/include/hw/s390x/s390_flic.h @@ -17,10 +17,12 @@ #include hw/s390x/adapter.h #include hw/virtio/virtio.h +#define ADAPTER_ROUTES_MAX_GSI 64 + typedef struct AdapterRoutes { AdapterInfo adapter; int num_routes; -int gsi[VIRTIO_PCI_QUEUE_MAX]; +int gsi[ADAPTER_ROUTES_MAX_GSI]; } AdapterRoutes; #define TYPE_S390_FLIC_COMMON s390-flic -- 2.1.0
Re: [Qemu-devel] [v7][PATCH 03/10] piix: create host bridge to passthrough
On Mi, 2015-03-18 at 17:06 +0800, Tiejun Chen wrote: Implement a pci host bridge specific to passthrough. Actually this just inherits the standard one. And we also just expose a minimal real host bridge pci configuration subset. +/* Here we just expose minimal host bridge offset subset. */ +static const IGDHostInfo igd_host_bridge_infos[] = { +{0x08, 2}, /* revision id */ +{0x2c, 2}, /* sybsystem vendor id */ +{0x2e, 2}, /* sybsystem id */ +{0x50, 2}, /* SNB: processor graphics control register */ +{0x52, 2}, /* processor graphics control register */ +{0xa4, 4}, /* SNB: graphics base of stolen memory */ +{0xa8, 4}, /* SNB: base of GTT stolen memory */ +}; Hmm, no vendor/device id here? Will the idg guest drivers happily read graphics control registers from i440fx even though this chipset never existed in a igd variant? [ just wondering, if it works that way fine, it certainly makes things easier for the firmware which uses host bridge pci id to figure whenever it is running @ i440fx or q35 ]. +static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev) +{ +uint32_t val = 0; +int rc, i, num; +int pos, len; + +num = ARRAY_SIZE(igd_host_bridge_infos); +for (i = 0; i num; i++) { +pos = igd_host_bridge_infos[i].offset; +len = igd_host_bridge_infos[i].len; +rc = host_pci_config_read(pos, len, val); +if (rc) { +return -ENODEV; +} +pci_default_write_config(pci_dev, pos, val, len); +} + +return 0; +} Nothing i440fx specific in here, just copying some host bridge pci config space bits. I guess we can sub-class the q35 host bridge the same way and even reuse the init function? +#define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE xen-igd-passthrough-i440FX One xen leftover slipped through here. cheers, Gerd
Re: [Qemu-devel] [RFC 0/5] Memory transaction attributes API
On Mon, Mar 16, 2015 at 05:20:17PM +, Peter Maydell wrote: This is an RFC patchset aimed at getting comment on some memory API changes to support transaction attributes, ie sideband information that goes along with a memory read or write access to define things like ARM secure/nonsecure, CPU/transaction master ID, privileged/nonprivileged. Hi Peter, Generally I think the direction of this looks very good, thanks! A few comments: 1. Would it make sense to instead of having the MemTxAttrs be a uint64_t instead have them be a struct with bitfields? We could still pass the struct by value I think and as long as it doesn't grow large the compiler will emit similar or the same code IIUC. 2. The series introduces the read and write _with_attrs. Another approach could be to add a (for example) single .access callback. The callback could take a structure pointer as input, e.g: struct MemTx { bool rw; hwaddr addr; int size; uint64_t data; MemTxAttrs attrs; } MemTxResult access(MemTx *tx) The benefit I see is that this will make it easier for us in the future to add new fields if needed. Best regards, Edgar (See also previous discussion: https://lists.nongnu.org/archive/html/qemu-devel/2014-09/msg01026.html ) Patch 1 is the API changes themselves: 1) new read_with_attrs and write_with_attrs fields in the MemoryRegionOps struct; the old read/write still exist for backwards compatibility, but devices that care about attributes can register with these function pointers instead 2) the functions return a success/failure status, so a device can actually fail bad transactions rather than merely returning bogus data. (This isn't wired up in this patchset but I include it to avoid revving the memory API twice.) Patches 2, 3 and 4 then plumb the memory attribute parameters through the various functions, working upwards to being able to put them in the iotlb. Patch 5 implements the target-arm changes to provide a secure/nonsecure tx attribute based on the page table walk, as a demonstration. There are obviously more APIs within QEMU for memory access functions which need to change to either always take a tx attribute, or to have extra with-tx-attribute versions of the functions. For the moment things are stubbed out with passing in no attributes specified values. I've modelled the transaction attributes as a (typedefed) uint64_t, whose bits will be defined as we find requirements for them (the meaning will not be per-architecture). When we originally discussed this on-list, Edgar suggested making the attributes be a (pointer to a) struct; however I found the ownership/copying semantics on this too awkward, because the access path needs to take attributes set up in the TLB and then modify them according to details of the access actually being made before passing them to the device, so took the simpler implementation route. I intend to continue working on this (filling in the gaps, etc), but wanted to send this series out early for comment on the memory API changes in particular. thanks -- PMM Peter Maydell (5): memory: Define API for MemoryRegionOps to take attrs and return status memory: Add MemTxAttrs argument to io_mem_read and io_mem_write Make CPU iotlb a structure rather than a plain hwaddr Add MemTxAttrs to the IOTLB target-arm: Honour NS bits in page tables cputlb.c | 22 +++--- exec.c | 29 +++--- hw/s390x/s390-pci-inst.c | 7 ++-- hw/vfio/pci.c| 4 +- include/exec/cpu-defs.h | 15 ++- include/exec/exec-all.h | 8 +++- include/exec/memattrs.h | 37 + include/exec/memory.h| 22 ++ memory.c | 102 +-- softmmu_template.h | 36 + target-arm/helper.c | 83 -- 11 files changed, 288 insertions(+), 77 deletions(-) create mode 100644 include/exec/memattrs.h -- 1.9.1
[Qemu-devel] [v7][PATCH 10/10] xen, gfx passthrough: add opregion mapping
The OpRegion shouldn't be mapped 1:1 because the address in the host can't be used in the guest directly. This patch traps read and write access to the opregion of the Intel GPU config space (offset 0xfc). The original patch is from Jean Guyader jean.guya...@eu.citrix.com Signed-off-by: Tiejun Chen tiejun.c...@intel.com Signed-off-by: Yang Zhang yang.z.zh...@intel.com --- hw/xen/xen_pt.h | 6 +++- hw/xen/xen_pt_config_init.c | 52 ++-- hw/xen/xen_pt_graphics.c| 82 + 3 files changed, 137 insertions(+), 3 deletions(-) diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h index d9b1ce0..20cc9b9 100644 --- a/hw/xen/xen_pt.h +++ b/hw/xen/xen_pt.h @@ -36,6 +36,9 @@ typedef struct XenPTReg XenPTReg; typedef struct XenPCIPassthroughState XenPCIPassthroughState; +uint32_t igd_read_opregion(XenPCIPassthroughState *s); +void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val); + /* function type for config reg */ typedef int (*xen_pt_conf_reg_init) (XenPCIPassthroughState *, XenPTRegInfo *, uint32_t real_offset, @@ -62,8 +65,9 @@ typedef int (*xen_pt_conf_byte_read) #define XEN_PT_BAR_ALLF 0x #define XEN_PT_BAR_UNMAPPED (-1) -#define PCI_CAP_MAX 48 +#define XEN_PCI_CAP_MAX 48 +#define XEN_PCI_INTEL_OPREGION 0xfc typedef enum { XEN_PT_GRP_TYPE_HARDWIRED = 0, /* 0 Hardwired reg group */ diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index d99c22e..abcfe1b 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -573,6 +573,22 @@ static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s, return 0; } +static int xen_pt_intel_opregion_read(XenPCIPassthroughState *s, + XenPTReg *cfg_entry, + uint32_t *value, uint32_t valid_mask) +{ +*value = igd_read_opregion(s); +return 0; +} + +static int xen_pt_intel_opregion_write(XenPCIPassthroughState *s, + XenPTReg *cfg_entry, uint32_t *value, + uint32_t dev_value, uint32_t valid_mask) +{ +igd_write_opregion(s, *value); +return 0; +} + /* Header Type0 reg static information table */ static XenPTRegInfo xen_pt_emu_reg_header0[] = { /* Vendor ID reg */ @@ -1438,6 +1454,20 @@ static XenPTRegInfo xen_pt_emu_reg_msix[] = { }, }; +static XenPTRegInfo xen_pt_emu_reg_igd_opregion[] = { +/* Intel IGFX OpRegion reg */ +{ +.offset = 0x0, +.size = 4, +.init_val = 0, +.no_wb = 1, +.u.dw.read = xen_pt_intel_opregion_read, +.u.dw.write = xen_pt_intel_opregion_write, +}, +{ +.size = 0, +}, +}; / * Capabilities @@ -1675,6 +1705,14 @@ static const XenPTRegGroupInfo xen_pt_emu_reg_grps[] = { .size_init = xen_pt_msix_size_init, .emu_regs = xen_pt_emu_reg_msix, }, +/* Intel IGD Opregion group */ +{ +.grp_id = XEN_PCI_INTEL_OPREGION, +.grp_type= XEN_PT_GRP_TYPE_EMU, +.grp_size= 0x4, +.size_init = xen_pt_reg_grp_size_init, +.emu_regs= xen_pt_emu_reg_igd_opregion, +}, { .grp_size = 0, }, @@ -1725,7 +1763,7 @@ out: static uint8_t find_cap_offset(XenPCIPassthroughState *s, uint8_t cap) { uint8_t id; -unsigned max_cap = PCI_CAP_MAX; +unsigned max_cap = XEN_PCI_CAP_MAX; uint8_t pos = PCI_CAPABILITY_LIST; uint8_t status = 0; @@ -1804,7 +1842,8 @@ int xen_pt_config_init(XenPCIPassthroughState *s) uint32_t reg_grp_offset = 0; XenPTRegGroup *reg_grp_entry = NULL; -if (xen_pt_emu_reg_grps[i].grp_id != 0xFF) { +if (xen_pt_emu_reg_grps[i].grp_id != 0xFF + xen_pt_emu_reg_grps[i].grp_id != XEN_PCI_INTEL_OPREGION) { if (xen_pt_hide_dev_cap(s-real_device, xen_pt_emu_reg_grps[i].grp_id)) { continue; @@ -1817,6 +1856,15 @@ int xen_pt_config_init(XenPCIPassthroughState *s) } } +/* + * By default we will trap up to 0x40 in the cfg space. + * If an intel device is pass through we need to trap 0xfc, + * therefore the size should be 0xff. + */ +if (xen_pt_emu_reg_grps[i].grp_id == XEN_PCI_INTEL_OPREGION) { +reg_grp_offset = XEN_PCI_INTEL_OPREGION; +} + reg_grp_entry = g_new0(XenPTRegGroup, 1); QLIST_INIT(reg_grp_entry-reg_tbl_list); QLIST_INSERT_HEAD(s-reg_grps, reg_grp_entry, entries); diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c index 3232296..df6069b 100644 --- a/hw/xen/xen_pt_graphics.c +++ b/hw/xen/xen_pt_graphics.c @@ -5,6 +5,11 @@ #include xen-host-pci-device.h #include hw/xen/xen_backend.h +static unsigned long igd_guest_opregion;
[Qemu-devel] [v7][PATCH 02/10] pc_init1: pass parameters just with types
Pass types to configure pc_init1(). Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- hw/i386/pc_piix.c | 17 +++-- 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 07faec9..cea3a5c 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -75,7 +75,9 @@ static bool has_reserved_memory = true; /* PC hardware initialisation */ static void pc_init1(MachineState *machine, int pci_enabled, - int kvmclock_enabled) + int kvmclock_enabled, + const char *host_type, + const char *pci_type) { PCMachineState *pc_machine = PC_MACHINE(machine); MemoryRegion *system_memory = get_system_memory(); @@ -202,8 +204,8 @@ static void pc_init1(MachineState *machine, } if (pci_enabled) { -pci_bus = i440fx_init(TYPE_I440FX_PCI_HOST_BRIDGE, - TYPE_I440FX_PCI_DEVICE, +pci_bus = i440fx_init(host_type, + pci_type, i440fx_state, piix3_devfn, isa_bus, gsi, system_memory, system_io, machine-ram_size, below_4g_mem_size, @@ -309,7 +311,8 @@ static void pc_init1(MachineState *machine, static void pc_init_pci(MachineState *machine) { -pc_init1(machine, 1, 1); +pc_init1(machine, 1, 1, TYPE_I440FX_PCI_HOST_BRIDGE, + TYPE_I440FX_PCI_DEVICE); } static void pc_compat_2_2(MachineState *machine) @@ -478,7 +481,8 @@ static void pc_init_pci_1_2(MachineState *machine) static void pc_init_pci_no_kvmclock(MachineState *machine) { pc_compat_1_2(machine); -pc_init1(machine, 1, 0); +pc_init1(machine, 1, 0, TYPE_I440FX_PCI_HOST_BRIDGE, + TYPE_I440FX_PCI_DEVICE); } static void pc_init_isa(MachineState *machine) @@ -495,7 +499,8 @@ static void pc_init_isa(MachineState *machine) } x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, 1 KVM_FEATURE_PV_EOI); enable_compat_apic_id_mode(); -pc_init1(machine, 0, 1); +pc_init1(machine, 0, 1, TYPE_I440FX_PCI_HOST_BRIDGE, + TYPE_I440FX_PCI_DEVICE); } #ifdef CONFIG_XEN -- 1.9.1
[Qemu-devel] [PATCH V4 15/19] virtio: introduce virtio_queue_get_index()
This patch introduces a helper that can get the queue index of a VirtQueue. This is useful when traversing the list of VirtQueues. Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/virtio/virtio.c | 5 + include/hw/virtio/virtio.h | 1 + 2 files changed, 6 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index ca157e8..d4c49ef 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -725,6 +725,11 @@ hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n) return vdev-vq[n].pa; } +int virtio_queue_get_index(VirtIODevice *vdev, VirtQueue *vq) +{ +return vq - vdev-vq; +} + void virtio_queue_set_num(VirtIODevice *vdev, int n, int num) { /* Don't allow guest to flip queue between existent and diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index e3adb1d..f148590 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -171,6 +171,7 @@ void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data); void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data); void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr); hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n); +int virtio_queue_get_index(VirtIODevice *vdev, VirtQueue *vq); void virtio_queue_set_num(VirtIODevice *vdev, int n, int num); int virtio_queue_get_num(VirtIODevice *vdev, int n); void virtio_queue_set_align(VirtIODevice *vdev, int n, int align); -- 2.1.0
[Qemu-devel] [PATCH V4 12/19] virtio-mmio: switch to bus specific queue limit
Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/virtio/virtio-mmio.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 2ae6942..dbd44b6 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -34,6 +34,8 @@ do { printf(virtio_mmio: fmt , ## __VA_ARGS__); } while (0) #define DPRINTF(fmt, ...) do {} while (0) #endif +#define VIRTIO_MMIO_QUEUE_MAX 64 + /* QOM macros */ /* virtio-mmio-bus */ #define TYPE_VIRTIO_MMIO_BUS virtio-mmio-bus @@ -237,7 +239,7 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value, proxy-guest_page_shift); break; case VIRTIO_MMIO_QUEUESEL: -if (value VIRTIO_PCI_QUEUE_MAX) { +if (value virtio_get_queue_max(vdev)) { vdev-queue_sel = value; } break; @@ -257,7 +259,7 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value, } break; case VIRTIO_MMIO_QUEUENOTIFY: -if (value VIRTIO_PCI_QUEUE_MAX) { +if (value virtio_get_queue_max(vdev)) { virtio_queue_notify(vdev, value); } break; @@ -403,7 +405,7 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data) k-device_plugged = virtio_mmio_device_plugged; k-has_variable_vring_alignment = true; bus_class-max_dev = 1; -k-queue_max = VIRTIO_PCI_QUEUE_MAX; +k-queue_max = VIRTIO_MMIO_QUEUE_MAX; } static const TypeInfo virtio_mmio_bus_info = { -- 2.1.0
Re: [Qemu-devel] [PATCH for-2.3] numa: pc: fix default VCPU to node mapping
On Tue, 17 Mar 2015 13:42:36 -0300 Eduardo Habkost ehabk...@redhat.com wrote: On Tue, Mar 17, 2015 at 03:48:38PM +, Igor Mammedov wrote: since commit dd0247e0 pc: acpi: mark all possible CPUs as enabled in SRAT Linux kernel actually tries to use CPU to Node mapping from QEMU provided SRAT table instead of discarding it, and that in some cases breaks build_sched_domains() which expects sane mapping where cores/threads belonging to the same socket are on the same NUMA node. With current default round-robin mapping of VCPUs to nodes guest ends-up with cores/threads belonging to the same socket being on different NUMA nodes. For example with following CLI: qemu-kvm -m 4G -smp 5,sockets=1,cores=4,threads=1,maxcpus=8 \ -numa node,nodeid=0 -numa node,nodeid=1 2.6.32 based kernels will hang on boot due to incorrectly build sched_group-s list in update_sd_lb_stats() so comment in QEMU justifying dumb default mapping: guest OSes must cope with this anyway, because there are BIOSes out there in real machines which also use this scheme. isn't really valid. Replacing default mapping withi a manual, where VCPUs belonging to the same socket are on the same NUMA node, fixes issue for guests which can't handle nonsense topology i.e. cnaging CLI to: -numa node,nodeid=0,cpus=0-3 -numa node,nodeid=1,cpus=4-7 So instead of simply scattering VCPUs around nodes, map the same socket VCPUs to the same NUMA node, which is what guest would expect from a sane hardware/BIOS. Signed-off-by: Igor Mammedov imamm...@redhat.com I believe the proposed behavior is much better. But if we are going to break compatibility, shouldn't we at least do that before the first -rc so we get feedback in case it break existing configurations? Aren't existing setups that actually care about node mapping typically do not use default mapping in favor of manually specifying which CPUs go to which node? BTW what it would break on already broken configuration? My thinking on this was that we prefer to not keep bugs in ACPI tables and fix them instead, since it doesn't affect currently running (migrating) guest and allows restarted guest use fixed ACPI tables. Considering that CPU info from SRAT is actually used only since 2.2, I'd prefer to fix it in 2.3 and 2.2 stable then allow default buggy SRAT spread over several releases. About qemu_cpu_socket_id_from_index(): all qemu-system-* binaries have smp_cores and smp_threads available (even if machines ignore it), but the default stub can return values that are larger than the number of sockets if smp_cores*smp_threads 1, which would be obviously incorrect. Isn't it easier to simply make cpu_index/(smp_cores*smp_sockets) be the default cpu_index-socket mapping function, and allow machine-specific (not arch-specific) overrides if necessary? Since it's hard-freeze now, patch focuses on fixing PC machine (which I can test) and do not affecting other targets (i.e. keep legacy behavior for them) that's why stub returns cpu_index. So I'd prefer hold off global cpu_index/(smp_cores*smp_sockets) change for now. So would something like below acceptable 2.3? node_id = cpu_index % nb_numa_nodes; if (machine_class-socket_from_cpu_index) { node_id = machine_class-socket_from_cpu_index(cpu_index) % nb_numa_nodes; } --- include/sysemu/cpus.h | 3 +++ numa.c| 14 ++ stubs/Makefile.objs | 1 + stubs/qemu_cpu_socket_id_from_index.c | 6 ++ target-i386/cpu.c | 11 +++ 5 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 stubs/qemu_cpu_socket_id_from_index.c diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 3f162a9..aacabcb 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -1,5 +1,6 @@ #ifndef QEMU_CPUS_H #define QEMU_CPUS_H +#include qemu-common.h /* cpus.c */ void qemu_init_cpu_loop(void); @@ -18,6 +19,8 @@ void qtest_clock_warp(int64_t dest); /* vl.c */ extern int smp_cores; extern int smp_threads; + +unsigned qemu_cpu_socket_id_from_index(unsigned int cpu_index); #else /* *-user doesn't have configurable SMP topology */ #define smp_cores 1 diff --git a/numa.c b/numa.c index ffbec68..5297749 100644 --- a/numa.c +++ b/numa.c @@ -26,6 +26,7 @@ #include exec/cpu-common.h #include qemu/bitmap.h #include qom/cpu.h +#include sysemu/cpus.h #include qemu/error-report.h #include include/exec/cpu-common.h /* for RAM_ADDR_FMT */ #include qapi-visit.h @@ -233,13 +234,18 @@ void parse_numa_opts(void) break; } } -/* assigning the VCPUs round-robin is easier to implement, guest OSes - * must cope with this anyway, because there are BIOSes out there in - * real
Re: [Qemu-devel] [PATCH] migration: flush the bdrv before stopping VM
[ Cc: qemu-block ] Am 18.03.2015 um 04:19 hat Li, Liang Z geschrieben: This needs further review/changes on the block layer. First explanation, why I think this don't fix the full problem. Whith this patch, we fix the problem where we have a dirty block layer but basically nothing dirtying the memory on the guest (we are moving the 20 seconds from max_downtime for the blocklayer flush), to 20 seconds until we have decided that the amount of dirty memory is small enough to be transferred during max_downtime. But it is still going to take 20 seconds to flush the block layer, and during that 20 seconds, the amount of memory that can be dirty is HUGE. It's true. What kind of cache is it actually that takes 20s to flush here? Inside of qemu, we don't cache a whole lot. If you use qcow2, we do use a writeback cache for some metadata that might need to be written back, but it is small and shouldn't take any significant time. Then we have the kernel page cache, or for some network protocols caches in the respective libs. This sounds like the right size for a 20s stall, but don't we require cache.direct=on for live migration anyway for coherency, i.e. bypassing any such cache? Lastly there may be a disk cache, but it's too small either. I think our ouptions are: - tell the block layer at the beggining of migration Hey, we are migrating, could you please start flusing data now, and don't get the caches to grow too much, please, pretty please. (I left the API to the block layer) - Add on that point a new function: bdrvr_flush_all_start() That starts the sending of pages, and we hope that by the time that we have migrated all memory, they have also finished (so our last call to block_flush_all() have less work to do) - Add another function: int bdrv_flush_all_timeout(int timeout) that returns if timeout pass, telling if it has migrated all pages or timeout has passed. So we can got back to the iterative stage if it has taken too long. The problem is that the block layer really doesn't have an option to control what is getting synced once the data is cached outside of qemu. Essentially we can do an fdatasync() or we can leave it, that's the only choice we have. Now doing an asynchronous fdatasync() in the background is completely reasonable in order to reduce the amount of data to be flushed later. But the patch is doing it while holding both the BQL and the AIOContext lock of the device, which doesn't feel right. Maybe it should schedule a BH in the AIOContext instead and flush from there asynchronously. The other thing is that flushing once doesn't mean that new data isn't accumulating in the cache, especially if you decide to do the background flush at the start of the migration. The obvious way to avoid that would be to switch to a writethrough mode, so any write request goes directly to the disk. This will, however, impact performance so heavily that it's probably not a realistic option. An alternative approach could be to repeat the background flush periodically, either time based or after every x bytes that are written to a device. Time based should actually be quite easy to implement. Once we have the flushing in the background, the migration code can apply any timeouts it wants. If the timeout is exceeded, the flush wouldn't be aborted but keep running in the background, but migration can go back to the iterative state anyway. Notice that *normally* bdrv_flush_all() is very fast, the problem is that sometimes it get really, really slow (NFS decided to go slow, TCP drop a packet, whatever). Right now, we don't have an interface to detect that cases and got back to the iterative stage. How about go back to the iterative stage when detect that the pending_size is larger Than max_size, like this: +/* do flush here is aimed to shorten the VM downtime, + * bdrv_flush_all is a time consuming operation + * when the guest has done some file writing */ +bdrv_flush_all(); +pending_size = qemu_savevm_state_pending(s-file, max_size); +if (pending_size pending_size = max_size) { +qemu_mutex_unlock_iothread(); +continue; +} ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); if (ret = 0) { qemu_file_set_rate_limit(s-file, INT64_MAX); and this is quite simple. Yes, but it is too simple. If you hold all the locks during bdrv_flush_all(), your VM will effectively stop as soon as it performs the next I/O access, so you don't win much. And you still don't have a timeout for cases where the flush takes really long. Kevin
[Qemu-devel] [PULL 02/19] util/uri: Add overflow check to rfc3986_parse_port
From: Max Reitz mre...@redhat.com And while at it, replace tabs by eight spaces in this function. Signed-off-by: Max Reitz mre...@redhat.com Message-Id: 1424887718-10800-2-git-send-email-mre...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- util/uri.c | 24 ++-- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/util/uri.c b/util/uri.c index 1cfd78b..550b984 100644 --- a/util/uri.c +++ b/util/uri.c @@ -320,19 +320,23 @@ static int rfc3986_parse_port(URI *uri, const char **str) { const char *cur = *str; +int port = 0; if (ISA_DIGIT(cur)) { - if (uri != NULL) - uri-port = 0; - while (ISA_DIGIT(cur)) { - if (uri != NULL) - uri-port = uri-port * 10 + (*cur - '0'); - cur++; - } - *str = cur; - return(0); +while (ISA_DIGIT(cur)) { +port = port * 10 + (*cur - '0'); +if (port 65535) { +return 1; +} +cur++; +} +if (uri) { +uri-port = port; +} +*str = cur; +return 0; } -return(1); +return 1; } /** -- 2.3.0
[Qemu-devel] [PULL 00/19] Misc bugfixes for 2.3.0-rc1
The following changes since commit cd232acfa0d70002fed89e9293f04afda577a513: Update version for v2.3.0-rc0 release (2015-03-17 18:58:33 +) are available in the git repository at: git://github.com/bonzini/qemu.git tags/for-upstream for you to fetch changes up to c3c1bb99d1c11978d9ce94d1bdcf0705378c1459: exec: Respect as_tranlsate_internal length clamp (2015-03-18 12:09:42 +0100) - kvm: ioeventfd fix for PPC64LE - virtio-scsi: misc fixes - fix for --enable-profiler - nbd: fixes from Max - build: fix for scripts/make_device_config.sh - exec: fix for address_space_translate Let's see if patchew likes the Message-Id tags from git-am. :) Alexey Kardashevskiy (1): profiler: Reenable built-in profiler Bo Su (1): virtio-scsi-dataplane: fix memory leak in virtio_scsi_vring_init Fam Zheng (1): virtio-scsi: Fix assert in virtio_scsi_push_event Greg Kurz (1): kvm: fix ioeventfd endianness on bi-endian architectures Max Reitz (12): util/uri: Add overflow check to rfc3986_parse_port qemu-nbd: Detect unused partitions by system == 0 nbd: Fix nbd_establish_connection()'s return value nbd: Pass return value from nbd_handle_list() nbd: Handle blk_getlength() failure qemu-nbd: fork() can fail nbd: Fix potential signed overflow issues nbd: Set block size to BDRV_SECTOR_SIZE nbd: Fix nbd_receive_options() nbd: Fix interpretation of the export flags nbd: Drop unexpected data for NBD_OPT_LIST coroutine-io: Return -errno in case of error Paolo Bonzini (1): build: pass .d file name to scripts/make_device_config.sh, fix makefile target Peter Crosthwaite (1): exec: Respect as_tranlsate_internal length clamp Yik Fang (1): nbd: Fix overflow return value Makefile| 3 +- block/nbd-client.c | 3 +- block/nbd-client.h | 1 - block/nbd.c | 2 +- blockdev-nbd.c | 6 ++- cpus.c | 2 +- exec.c | 6 +-- hw/scsi/virtio-scsi-dataplane.c | 4 +- hw/scsi/virtio-scsi.c | 8 ++- include/block/nbd.h | 11 ++-- include/qemu/timer.h| 5 +- kvm-all.c | 24 - monitor.c | 6 +-- nbd.c | 112 qemu-coroutine-io.c | 2 +- qemu-nbd.c | 30 +++ scripts/make_device_config.sh | 18 --- util/uri.c | 24 + 18 files changed, 178 insertions(+), 89 deletions(-) -- 2.3.0
[Qemu-devel] [PULL 04/19] nbd: Fix nbd_establish_connection()'s return value
From: Max Reitz mre...@redhat.com unix_connect_opts() and inet_connect_opts() do not necessarily set errno (if at all); therefore, nbd_establish_connection() should not literally return -errno on error. Signed-off-by: Max Reitz mre...@redhat.com Message-Id: 1424887718-10800-4-git-send-email-mre...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- block/nbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/nbd.c b/block/nbd.c index 6634a69..2176186 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -248,7 +248,7 @@ static int nbd_establish_connection(BlockDriverState *bs, Error **errp) /* Failed to establish connection */ if (sock 0) { logout(Failed to establish connection to NBD server\n); -return -errno; +return -EIO; } return sock; -- 2.3.0
[Qemu-devel] [PATCH v4 1/3] uhci: fix segfault when hot-unplugging uhci controller
From: Gonglei arei.gong...@huawei.com When hot-unplugging the usb controllers (ehci/uhci), we have to clean all resouce of these devices, involved registered reset handler. Otherwise, it may cause NULL pointer access and/or segmentation fault if we reboot the guest os after hot-unplugging. Let's hook up reset via DeviceClass-reset() and drop the qemu_register_reset() call. Then Qemu will register and unregister the reset handler automatically. Cc: qemu-stable qemu-sta...@nongnu.org Reported-by: Lidonglin lidong...@huawei.com Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/usb/hcd-uhci.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index f903de7..d8f0577 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -348,9 +348,10 @@ static void uhci_update_irq(UHCIState *s) pci_set_irq(s-dev, level); } -static void uhci_reset(void *opaque) +static void uhci_reset(DeviceState *dev) { -UHCIState *s = opaque; +PCIDevice *d = PCI_DEVICE(dev); +UHCIState *s = DO_UPCAST(UHCIState, dev, d); uint8_t *pci_conf; int i; UHCIPort *port; @@ -454,11 +455,11 @@ static void uhci_port_write(void *opaque, hwaddr addr, port = s-ports[i]; usb_device_reset(port-port.dev); } -uhci_reset(s); +uhci_reset(DEVICE(s)); return; } if (val UHCI_CMD_HCRESET) { -uhci_reset(s); +uhci_reset(DEVICE(s)); return; } s-cmd = val; @@ -1226,8 +1227,6 @@ static int usb_uhci_common_initfn(PCIDevice *dev) s-num_ports_vmstate = NB_PORTS; QTAILQ_INIT(s-queues); -qemu_register_reset(uhci_reset, s); - memory_region_init_io(s-io_bar, OBJECT(s), uhci_ioport_ops, s, uhci, 0x20); @@ -1303,6 +1302,7 @@ static void uhci_class_init(ObjectClass *klass, void *data) k-revision = info-revision; k-class_id = PCI_CLASS_SERIAL_USB; dc-vmsd = vmstate_uhci; +dc-reset = uhci_reset; if (!info-unplug) { /* uhci controllers in companion setups can't be hotplugged */ dc-hotpluggable = false; -- 1.7.12.4
[Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter
From: Gonglei arei.gong...@huawei.com When hot-unplugging the usb controllers (ehci/uhci), we have to clean all resouce of these devices, involved registered reset handler. Otherwise, it may cause NULL pointer access and/or segmentation fault if we reboot the guest os after hot-unplugging. Let's hook up reset via DeviceClass-reset() and drop the qemu_register_reset() call. Then Qemu will register and unregister the reset handler automatically. Cc: qemu-stable qemu-sta...@nongnu.org v4 - v3: - add reset hookup for sysbus devices (ehci/ohci). (Gerd) v2 - v3: - rewrite each patch's title v1 - v2: - hooking up reset via DeviceClass-reset and drop the qemu_register_reset() calls. (Gerd) Gonglei (3): uhci: fix segfault when hot-unplugging uhci controller ehci: fix segfault when hot-unplugging ehci controller ohci: fix resource cleanup leak hw/usb/hcd-ehci-pci.c| 10 ++ hw/usb/hcd-ehci-sysbus.c | 10 ++ hw/usb/hcd-ehci.c| 3 +-- hw/usb/hcd-ehci.h| 1 + hw/usb/hcd-ohci.c| 20 +++- hw/usb/hcd-uhci.c| 12 ++-- 6 files changed, 47 insertions(+), 9 deletions(-) -- 1.7.12.4
[Qemu-devel] [PATCH V4 17/19] virtio-pci: increase the maximum number of virtqueues to 513
This patch increases the maximum number of virtqueues for pci from 64 to 513. This will allow booting a virtio-net-pci device with 256 queue pairs. To keep migration compatibility, 64 was kept for legacy machine types. This is because qemu in fact allows guest to probe the limit of virtqueues through trying to set queue_sel. So for legacy machine type, we should make sure setting queue_sel to more than 63 won't make effect. Cc: Paolo Bonzini pbonz...@redhat.com Cc: Richard Henderson r...@twiddle.net Cc: Michael S. Tsirkin m...@redhat.com Cc: Alexander Graf ag...@suse.de Cc: qemu-...@nongnu.org Signed-off-by: Jason Wang jasow...@redhat.com --- hw/i386/pc_piix.c | 5 + hw/i386/pc_q35.c | 5 + hw/ppc/spapr.c | 5 + hw/virtio/virtio-pci.c | 2 +- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 175e582..0796719 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -49,6 +49,7 @@ #include hw/acpi/acpi.h #include cpu.h #include qemu/error-report.h +#include hw/virtio/virtio-bus.h #ifdef CONFIG_XEN # include xen/hvm/hvm_info_table.h #endif @@ -312,6 +313,10 @@ static void pc_init_pci(MachineState *machine) static void pc_compat_2_3(MachineState *machine) { +ObjectClass *klass = object_class_by_name(virtio-pci-bus); +VirtioBusClass *k = VIRTIO_BUS_CLASS(klass); + +k-queue_max = 64; } static void pc_compat_2_2(MachineState *machine) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index df44d25..a8a34a4 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -45,6 +45,7 @@ #include hw/usb.h #include hw/cpu/icc_bus.h #include qemu/error-report.h +#include include/hw/virtio/virtio-bus.h /* ICH9 AHCI has 6 ports */ #define MAX_SATA_PORTS 6 @@ -291,6 +292,10 @@ static void pc_q35_init(MachineState *machine) static void pc_compat_2_3(MachineState *machine) { +ObjectClass *klass = object_class_by_name(virtio-pci-bus); +VirtioBusClass *k = VIRTIO_BUS_CLASS(klass); + +k-queue_max = 64; } static void pc_compat_2_2(MachineState *machine) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 22f4ae4..5f25dd3 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -50,6 +50,7 @@ #include hw/pci/pci.h #include hw/scsi/scsi.h #include hw/virtio/virtio-scsi.h +#include hw/virtio/virtio-bus.h #include exec/address-spaces.h #include hw/usb.h @@ -1805,6 +1806,10 @@ static const TypeInfo spapr_machine_info = { static void spapr_compat_2_3(Object *obj) { +ObjectClass *klass = object_class_by_name(virtio-pci-bus); +VirtioBusClass *k = VIRTIO_BUS_CLASS(klass); + +k-queue_max = 64; } static void spapr_compat_2_2(Object *obj) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 9a5242a..02e3ce8 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -42,7 +42,7 @@ * configuration space */ #define VIRTIO_PCI_CONFIG_SIZE(dev) VIRTIO_PCI_CONFIG_OFF(msix_enabled(dev)) -#define VIRTIO_PCI_QUEUE_MAX 64 +#define VIRTIO_PCI_QUEUE_MAX 513 static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size, VirtIOPCIProxy *dev); -- 2.1.0
[Qemu-devel] [PATCH V4 19/19] virtio-pci: introduce auto_msix_bar_size property
Currently we don't support more than 128 MSI-X vectors for a pci devices, trying to use vector=129 for a virtio-net-pci device may get: qemu-system-x86_64: -device virtio-net-pci,netdev=hn0,vectors=129: unable to init msix vectors to 129 This this because the MSI-X bar size were hard-coded as 4096. So this patch introduces boolean auto_msix_bar_size property for virito-pci devices. Enable this will let the device calculate the msix bar size based on the number of MSI-X entries instead of previous 4096 hard-coded limit. This is a must to let virtio-net can up to 256 queues and each queue were associated with a specific MSI-X entry. Cc: Paolo Bonzini pbonz...@redhat.com Cc: Richard Henderson r...@twiddle.net Cc: Michael S. Tsirkin m...@redhat.com Cc: Alexander Graf ag...@suse.de Cc: qemu-...@nongnu.org Signed-off-by: Jason Wang jasow...@redhat.com --- hw/i386/pc_piix.c | 8 hw/i386/pc_q35.c | 8 hw/ppc/spapr.c | 11 ++- hw/virtio/virtio-pci.c | 17 +++-- hw/virtio/virtio-pci.h | 3 +++ include/hw/compat.h| 11 +++ 6 files changed, 55 insertions(+), 3 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 0796719..8808500 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -552,6 +552,10 @@ static QEMUMachine pc_i440fx_machine_v2_3 = { PC_I440FX_2_3_MACHINE_OPTIONS, .name = pc-i440fx-2.3, .init = pc_init_pci_2_3, +.compat_props = (GlobalProperty[]) { +HW_COMPAT_2_3, +{ /* end of list */ } +}, }; #define PC_I440FX_2_2_MACHINE_OPTIONS PC_I440FX_2_3_MACHINE_OPTIONS @@ -560,6 +564,10 @@ static QEMUMachine pc_i440fx_machine_v2_2 = { PC_I440FX_2_2_MACHINE_OPTIONS, .name = pc-i440fx-2.2, .init = pc_init_pci_2_2, +.compat_props = (GlobalProperty[]) { +HW_COMPAT_2_2, +{ /* end of list */ } +}, }; #define PC_I440FX_2_1_MACHINE_OPTIONS \ diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index a8a34a4..4a34349 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -448,6 +448,10 @@ static QEMUMachine pc_q35_machine_v2_3 = { PC_Q35_2_3_MACHINE_OPTIONS, .name = pc-q35-2.3, .init = pc_q35_init_2_3, +.compat_props = (GlobalProperty[]) { +HW_COMPAT_2_3, +{ /* end of list */ } +}, }; #define PC_Q35_2_2_MACHINE_OPTIONS PC_Q35_2_3_MACHINE_OPTIONS @@ -456,6 +460,10 @@ static QEMUMachine pc_q35_machine_v2_2 = { PC_Q35_2_2_MACHINE_OPTIONS, .name = pc-q35-2.2, .init = pc_q35_init_2_2, +.compat_props = (GlobalProperty[]) { +HW_COMPAT_2_2, +{ /* end of list */ } +}, }; #define PC_Q35_2_1_MACHINE_OPTIONS \ diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5f25dd3..853a5cc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1794,12 +1794,16 @@ static const TypeInfo spapr_machine_info = { }, }; +#define SPAPR_COMPAT_2_3 \ +HW_COMPAT_2_3 + #define SPAPR_COMPAT_2_2 \ +SPAPR_COMPAT_2_3, \ {\ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\ .property = mem_win_size,\ .value= 0x2000,\ -} +} \ #define SPAPR_COMPAT_2_1 \ SPAPR_COMPAT_2_2 @@ -1883,10 +1887,15 @@ static const TypeInfo spapr_machine_2_2_info = { static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data) { +static GlobalProperty compat_props[] = { +SPAPR_COMPAT_2_3, +{ /* end of list */ } +}; MachineClass *mc = MACHINE_CLASS(oc); mc-name = pseries-2.3; mc-desc = pSeries Logical Partition (PAPR compliant) v2.3; +mc-compat_props = compat_props; } static const TypeInfo spapr_machine_2_3_info = { diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 4a5febb..f4cd405 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -925,7 +925,7 @@ static void virtio_pci_device_plugged(DeviceState *d) VirtIOPCIProxy *proxy = VIRTIO_PCI(d); VirtioBusState *bus = proxy-bus; uint8_t *config; -uint32_t size; +uint32_t size, bar_size; config = proxy-pci_dev.config; if (proxy-class_code) { @@ -936,8 +936,19 @@ static void virtio_pci_device_plugged(DeviceState *d) pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus)); config[PCI_INTERRUPT_PIN] = 1; +if (proxy-flags VIRTIO_PCI_FLAG_AUTO_MSIX_SIZE) { +bar_size = proxy-nvectors * PCI_MSIX_ENTRY_SIZE * 2; +if (bar_size (bar_size - 1)) { +bar_size = 1 qemu_fls(bar_size); +} +} else { +/* For migration compatibility */ +bar_size = 4096; +} + if (proxy-nvectors -msix_init_exclusive_bar(proxy-pci_dev, proxy-nvectors, 1, 4096)) { +msix_init_exclusive_bar(proxy-pci_dev, proxy-nvectors, 1, +bar_size)) { error_report(unable to init msix vectors to % PRIu32,
[Qemu-devel] [PATCH v4 3/3] ohci: fix resource cleanup leak
From: Gonglei arei.gong...@huawei.com When hot-unplugging the usb controllers (ehci/uhci), we have to clean all resouce of these devices, involved registered reset handler. Otherwise, it may cause NULL pointer access and/or segmentation fault if we reboot the guest os after hot-unplugging. Let's hook up reset via DeviceClass-reset() and drop the qemu_register_reset() call. Then Qemu will register and unregister the reset handler automatically. Ohci does't support hotplugging/hotunplugging yet, but existing resource cleanup leak logic likes ehci/uhci. Cc: qemu-stable qemu-sta...@nongnu.org Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/usb/hcd-ohci.c | 20 +++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index a0d478e..ca7aeb3 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -1879,7 +1879,6 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev, usb_packet_init(ohci-usb_packet); ohci-async_td = 0; -qemu_register_reset(ohci_reset, ohci); return 0; } @@ -1951,6 +1950,15 @@ static void usb_ohci_exit(PCIDevice *dev) } } +static void usb_ohci_reset_pci(DeviceState *d) +{ +PCIDevice *dev = PCI_DEVICE(d); +OHCIPCIState *ohci = PCI_OHCI(dev); +OHCIState *s = ohci-state; + +ohci_reset(s); +} + #define TYPE_SYSBUS_OHCI sysbus-ohci #define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI) @@ -1976,6 +1984,14 @@ static void ohci_realize_pxa(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, s-ohci.mem); } +static void usb_ohci_reset_sysbus(DeviceState *dev) +{ +OHCISysBusState *s = SYSBUS_OHCI(dev); +OHCIState *ohci = s-ohci; + +ohci_reset(ohci); +} + static Property ohci_pci_properties[] = { DEFINE_PROP_STRING(masterbus, OHCIPCIState, masterbus), DEFINE_PROP_UINT32(num-ports, OHCIPCIState, num_ports, 3), @@ -2097,6 +2113,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data) dc-props = ohci_pci_properties; dc-hotpluggable = false; dc-vmsd = vmstate_ohci; +dc-reset = usb_ohci_reset_pci; } static const TypeInfo ohci_pci_info = { @@ -2120,6 +2137,7 @@ static void ohci_sysbus_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_USB, dc-categories); dc-desc = OHCI USB Controller; dc-props = ohci_sysbus_properties; +dc-reset = usb_ohci_reset_sysbus; } static const TypeInfo ohci_sysbus_info = { -- 1.7.12.4
Re: [Qemu-devel] [PATCH] exec: Respect as_tranlsate_internal length clamp
On 17/03/2015 06:35, Peter Crosthwaite wrote: address_space_translate_internal will clamp the *plen length argument based on the size of the memory region being queried. The iommu walker logic in addresss_space_translate was ignoring this by discarding the post fn call value of *plen. Fix by just always using *plen as the length argument throughout the fn, removing the len local variable. This fixes a bootloader bug when a single elf section spans multiple QEMU memory regions. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- exec.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/exec.c b/exec.c index e97071a..8b922db 100644 --- a/exec.c +++ b/exec.c @@ -380,7 +380,6 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, IOMMUTLBEntry iotlb; MemoryRegionSection *section; MemoryRegion *mr; -hwaddr len = *plen; rcu_read_lock(); for (;;) { @@ -395,7 +394,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, iotlb = mr-iommu_ops-translate(mr, addr, is_write); addr = ((iotlb.translated_addr ~iotlb.addr_mask) | (addr iotlb.addr_mask)); -len = MIN(len, (addr | iotlb.addr_mask) - addr + 1); +*plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1); if (!(iotlb.perm (1 is_write))) { mr = io_mem_unassigned; break; @@ -406,10 +405,9 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, if (xen_enabled() memory_access_is_direct(mr, is_write)) { hwaddr page = ((addr TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr; -len = MIN(page, len); +*plen = MIN(page, *plen); } -*plen = len; *xlat = addr; rcu_read_unlock(); return mr; Applied, thanks. Paolo
Re: [Qemu-devel] [PATCH v3 2/3] ehci: fix segfault when hot-unplugging ehci controller
On 2015/3/18 16:23, Gerd Hoffmann wrote: On Mi, 2015-03-18 at 09:49 +0800, arei.gong...@huawei.com wrote: From: Gonglei arei.gong...@huawei.com When hot-unplugging the usb controllers (ehci/uhci), we have to clean all resouce of these devices, involved registered reset handler. Otherwise, it may cause NULL pointer access and/or segmentation fault if we reboot the guest os after hot-unplugging. Let's hook up reset via DeviceClass-reset() and drop the qemu_register_reset() call. Then Qemu will register and unregister the reset handler automatically. Fails make check (for aarch64). My guess is the sysbus variants lost the reset hookup. Actually, these fails were introduced by the follow patch: commit c3cf77cb63b71618224129df41f114488e0f74e4 Author: David Gibson da...@gibson.dropbear.id.au Date: Wed Feb 18 16:01:01 2015 +1100 Make sysbus EHCI devices ARM only by default A number of ARM embedded boards include EHCI USB host controllers which appear as directly mapped devices, rather than sitting on a PCI bus. At present code to emulate such devices is included whenever EHCI support is included. This patch adjusts teh config options to only include them in builds targetting ARM by default. But on the other hand, the sysbus variants lost the reset hookup is a real bug, I will fix them in the next version. thanks! Regards, -Gonglei
[Qemu-devel] [PATCH V4 16/19] virtio-pci: speedup MSI-X masking and unmasking
This patch tries to speed up the MSI-X masking and unmasking through the mapping between vector and queues. With this patch it will there's no need to go through all possible virtqueues, which may help to reduce the time spent when doing MSI-X masking/unmasking a single vector when more than hundreds or even thousands of virtqueues were supported. Tested with 80 queue pairs virito-net-pci by changing the smp affinity in the background and doing netperf in the same time: Before the patch: 5711.70 Gbits/sec After the patch: 6830.98 Gbits/sec About 19.6% improvements in throughput. Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/virtio/virtio-pci.c | 40 +--- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index c38f33f..9a5242a 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -632,28 +632,30 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, { VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); VirtIODevice *vdev = virtio_bus_get_device(proxy-bus); -int ret, queue_no; +VirtQueue *vq = virtio_vector_first_queue(vdev, vector); +int ret, index, unmasked = 0; -for (queue_no = 0; queue_no proxy-nvqs_with_notifiers; queue_no++) { -if (!virtio_queue_get_num(vdev, queue_no)) { +while (vq) { +index = virtio_queue_get_index(vdev, vq); +if (!virtio_queue_get_num(vdev, index)) { break; } -if (virtio_queue_vector(vdev, queue_no) != vector) { -continue; -} -ret = virtio_pci_vq_vector_unmask(proxy, queue_no, vector, msg); +ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg); if (ret 0) { goto undo; } +vq = virtio_vector_next_queue(vq); +++unmasked; } + return 0; undo: -while (--queue_no = 0) { -if (virtio_queue_vector(vdev, queue_no) != vector) { -continue; -} -virtio_pci_vq_vector_mask(proxy, queue_no, vector); +vq = virtio_vector_first_queue(vdev, vector); +while (vq --unmasked = 0) { +index = virtio_queue_get_index(vdev, vq); +virtio_pci_vq_vector_mask(proxy, index, vector); +vq = virtio_vector_next_queue(vq); } return ret; } @@ -662,16 +664,16 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector) { VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); VirtIODevice *vdev = virtio_bus_get_device(proxy-bus); -int queue_no; +VirtQueue *vq = virtio_vector_first_queue(vdev, vector); +int index; -for (queue_no = 0; queue_no proxy-nvqs_with_notifiers; queue_no++) { -if (!virtio_queue_get_num(vdev, queue_no)) { +while (vq) { +index = virtio_queue_get_index(vdev, vq); +if (!virtio_queue_get_num(vdev, index)) { break; } -if (virtio_queue_vector(vdev, queue_no) != vector) { -continue; -} -virtio_pci_vq_vector_mask(proxy, queue_no, vector); +virtio_pci_vq_vector_mask(proxy, index, vector); +vq = virtio_vector_next_queue(vq); } } -- 2.1.0
[Qemu-devel] [PATCH V4 06/19] virtio-ccw: using VIRTIO_NO_VECTOR instead of 0 for invalid virtqueue
There's no need to use vector 0 for invalid virtqueue. So this patch changes to use VIRTIO_NO_VECTOR instead. Cc: Michael S. Tsirkin m...@redhat.com Cc: Cornelia Huck cornelia.h...@de.ibm.com CC: Christian Borntraeger borntrae...@de.ibm.com Cc: Richard Henderson r...@twiddle.net Cc: Alexander Graf ag...@suse.de Signed-off-by: Jason Wang jasow...@redhat.com --- hw/s390x/virtio-ccw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 130535c..c8b87aa 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -281,7 +281,7 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, virtio_queue_set_addr(vdev, index, addr); if (!addr) { -virtio_queue_set_vector(vdev, index, 0); +virtio_queue_set_vector(vdev, index, VIRTIO_NO_VECTOR); } else { /* Fail if we don't have a big enough queue. */ /* TODO: Add interface to handle vring.num changing */ -- 2.1.0
[Qemu-devel] [PATCH V4 09/19] virito: introduce bus specific queue limit
This patch introduces a bus specific queue limitation. It will be useful for increasing the limit for one of the bus without disturbing other buses. Cc: Michael S. Tsirkin m...@redhat.com Cc: Alexander Graf ag...@suse.de Cc: Richard Henderson r...@twiddle.net Cc: Cornelia Huck cornelia.h...@de.ibm.com Cc: Christian Borntraeger borntrae...@de.ibm.com Cc: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/char/virtio-serial-bus.c| 2 +- hw/net/virtio-net.c| 4 ++-- hw/s390x/s390-virtio-bus.c | 1 + hw/s390x/virtio-ccw.c | 1 + hw/scsi/virtio-scsi.c | 4 ++-- hw/virtio/virtio-mmio.c| 1 + hw/virtio/virtio-pci.c | 1 + hw/virtio/virtio.c | 40 +--- include/hw/virtio/virtio-bus.h | 1 + include/hw/virtio/virtio.h | 1 + 10 files changed, 36 insertions(+), 20 deletions(-) diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index c86814f..dec2f2d 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -942,7 +942,7 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp) } /* Each port takes 2 queues, and one pair is for the control queue */ -max_supported_ports = VIRTIO_PCI_QUEUE_MAX / 2 - 1; +max_supported_ports = virtio_get_queue_max(vdev) / 2 - 1; if (vser-serial.max_virtserial_ports max_supported_ports) { error_setg(errp, maximum ports supported: %u, max_supported_ports); diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index b6fac9c..bf286f5 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1588,10 +1588,10 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) virtio_init(vdev, virtio-net, VIRTIO_ID_NET, n-config_size); n-max_queues = MAX(n-nic_conf.peers.queues, 1); -if (n-max_queues * 2 + 1 VIRTIO_PCI_QUEUE_MAX) { +if (n-max_queues * 2 + 1 virtio_get_queue_max(vdev)) { error_setg(errp, Invalid number of queues (= % PRIu32 ), must be a postive integer less than %d., - n-max_queues, (VIRTIO_PCI_QUEUE_MAX - 1) / 2); + n-max_queues, (virtio_get_queue_max(vdev) - 1) / 2); virtio_cleanup(vdev); return; } diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 047c963..2b41e32 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -715,6 +715,7 @@ static void virtio_s390_bus_class_init(ObjectClass *klass, void *data) bus_class-max_dev = 1; k-notify = virtio_s390_notify; k-get_features = virtio_s390_get_features; +k-queue_max = VIRTIO_PCI_QUEUE_MAX; } static const TypeInfo virtio_s390_bus_info = { diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index c8b87aa..dfe6ded 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1711,6 +1711,7 @@ static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data) k-load_queue = virtio_ccw_load_queue; k-save_config = virtio_ccw_save_config; k-load_config = virtio_ccw_load_config; +k-queue_max = VIRTIO_PCI_QUEUE_MAX; } static const TypeInfo virtio_ccw_bus_info = { diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index da0cff8..feb5e07 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -822,10 +822,10 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp, sizeof(VirtIOSCSIConfig)); if (s-conf.num_queues == 0 || -s-conf.num_queues VIRTIO_PCI_QUEUE_MAX - 2) { +s-conf.num_queues virtio_get_queue_max(vdev) - 2) { error_setg(errp, Invalid number of queues (= % PRIu32 ), must be a positive integer less than %d., - s-conf.num_queues, VIRTIO_PCI_QUEUE_MAX - 2); + s-conf.num_queues, virtio_get_queue_max(vdev) - 2); virtio_cleanup(vdev); return; } diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 10123f3..2ae6942 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -403,6 +403,7 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data) k-device_plugged = virtio_mmio_device_plugged; k-has_variable_vring_alignment = true; bus_class-max_dev = 1; +k-queue_max = VIRTIO_PCI_QUEUE_MAX; } static const TypeInfo virtio_mmio_bus_info = { diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index c7c3f72..075b13b 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1498,6 +1498,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data) k-vmstate_change = virtio_pci_vmstate_change; k-device_plugged = virtio_pci_device_plugged; k-device_unplugged = virtio_pci_device_unplugged; +k-queue_max = VIRTIO_PCI_QUEUE_MAX; } static const TypeInfo virtio_pci_bus_info = { diff --git
[Qemu-devel] [PATCH V4 04/19] monitor: replace the magic number 255 with MAX_QUEUE_NUM
This patch replace the magic number 255, and increase it to MAX_QUEUE_NUM which is maximum number of queues supported by a nic. Cc: Luiz Capitulino lcapitul...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- monitor.c | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/monitor.c b/monitor.c index 42116a9..07dfed0 100644 --- a/monitor.c +++ b/monitor.c @@ -4475,10 +4475,11 @@ void set_link_completion(ReadLineState *rs, int nb_args, const char *str) len = strlen(str); readline_set_completion_index(rs, len); if (nb_args == 2) { -NetClientState *ncs[255]; +NetClientState *ncs[MAX_QUEUE_NUM]; int count, i; count = qemu_find_net_clients_except(NULL, ncs, - NET_CLIENT_OPTIONS_KIND_NONE, 255); + NET_CLIENT_OPTIONS_KIND_NONE, + MAX_QUEUE_NUM); for (i = 0; i count; i++) { const char *name = ncs[i]-name; if (!strncmp(str, name, len)) { @@ -4494,7 +4495,7 @@ void set_link_completion(ReadLineState *rs, int nb_args, const char *str) void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str) { int len, count, i; -NetClientState *ncs[255]; +NetClientState *ncs[MAX_QUEUE_NUM]; if (nb_args != 2) { return; @@ -4503,7 +4504,7 @@ void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str) len = strlen(str); readline_set_completion_index(rs, len); count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NIC, - 255); + MAX_QUEUE_NUM); for (i = 0; i count; i++) { QemuOpts *opts; const char *name = ncs[i]-name; @@ -4569,14 +4570,15 @@ void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str) void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str) { -NetClientState *ncs[255]; +NetClientState *ncs[MAX_QUEUE_NUM]; int count, i, len; len = strlen(str); readline_set_completion_index(rs, len); if (nb_args == 2) { count = qemu_find_net_clients_except(NULL, ncs, - NET_CLIENT_OPTIONS_KIND_NONE, 255); + NET_CLIENT_OPTIONS_KIND_NONE, + MAX_QUEUE_NUM); for (i = 0; i count; i++) { int id; char name[16]; @@ -4592,7 +4594,8 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str) return; } else if (nb_args == 3) { count = qemu_find_net_clients_except(NULL, ncs, - NET_CLIENT_OPTIONS_KIND_NIC, 255); + NET_CLIENT_OPTIONS_KIND_NIC, + MAX_QUEUE_NUM); for (i = 0; i count; i++) { int id; const char *name; -- 2.1.0
[Qemu-devel] [v7][PATCH 00/10] xen: add Intel IGD passthrough support
v7: * Instead of -gfx_passthru we'd like to make that a machine option, -machine xxx,igd-passthru=on * try to make something as common shared by others like KvmGT in the future * Just read those real value from host bridge pci configuration space when create host bridge then put in dev-config. v6: * Drop introducing a new machine specific to IGD passthrough * Try to share some codes from KVM stuff in qemu to retrive VGA BIOS * Currently IGD drivers always need to access PCH by 1f.0. But we don't want to poke that directly to get ID, and although in real world different GPU should have different PCH. But actually the different PCH DIDs likely map to different PCH SKUs. We do the same thing for the GPU. For PCH, the different SKUs are going to be all the same silicon design and implementation, just different features turn on and off with fuses. The SW interfaces should be consistent across all SKUs in a given family (eg LPT). But just same features may not be supported. Most of these different PCH features probably don't matter to the Gfx driver, but obviously any difference in display port connections will so it should be fine with any PCH in case of passthrough. So currently use one PCH version, 0x8c4e, to cover all HSW(Haswell) scenarios, 0x9cc3 for BDW(Broadwell). * Drop igd write ops since its fine to emulate that, and we also shrink those igd read ops as necessary. * Rebase and cleanup all patches. v5: * Simplify to make sure its really inherited from the standard one in patch #3 * Then drop the original patch #3 v4: * Rebase on latest tree * Drop patch #2 * Regenerate patches after Michael introduce patch #1 * We need to use this pci_type as a index to reuse I440FX_PCI_DEVICE() * Test: boot with a preinstalled winxp ./i386-softmmu/qemu-system-i386 -hda winxp-32.img -m 2560 -boot c -machine pc v3: * Drop patch #4 * Add one patch #1 from Michael * Rebase * In./i386-softmmu/qemu-system-i386 -hda test.img -m 2560 -boot c -machine pc v2: * Fix some coding style * New patch to separate i440fx_init * Just add prefix with XEN_IGD_PASSTHROUGH/xen_igd_passthrough * Based on patch #2 to regenerate * Unify prefix with XEN_IGD_PASSTHROUGH/xen_igd_passthrough like patch #3 * Test: boot with a preinstalled ubuntu 14.04 ./i386-softmmu/qemu-system-i386 -hda test.img -m 2560 -boot c -machine pc As we discussed we need to create a separate machine to support current IGD passthrough. Michael S. Tsirkin (1): i440fx: make types configurable at run-time Tiejun Chen (9): pc_init1: pass parameters just with types piix: create host bridge to passthrough hw/pci-assign: split pci-assign.c xen, gfx passthrough: basic graphics passthrough support xen, gfx passthrough: retrieve VGA BIOS to work igd gfx passthrough: create a isa bridge xen, gfx passthrough: register a isa bridge xen, gfx passthrough: register host bridge specific to passthrough xen, gfx passthrough: add opregion mapping hw/core/machine.c | 20 +++ hw/i386/Makefile.objs | 1 + hw/i386/kvm/pci-assign.c | 82 +- hw/i386/pc_piix.c | 149 ++- hw/i386/pci-assign-load-rom.c | 93 hw/pci-host/piix.c| 91 +++- hw/xen/Makefile.objs | 1 + hw/xen/xen-host-pci-device.c | 5 + hw/xen/xen-host-pci-device.h | 1 + hw/xen/xen_pt.c | 32 hw/xen/xen_pt.h | 21 ++- hw/xen/xen_pt_config_init.c | 52 ++- hw/xen/xen_pt_graphics.c | 272 ++ include/hw/boards.h | 1 + include/hw/i386/pc.h | 8 +- include/hw/pci/pci-assign.h | 27 include/hw/xen/xen.h | 1 + qemu-options.hx | 3 + vl.c | 10 ++ 19 files changed, 778 insertions(+), 92 deletions(-) create mode 100644 hw/i386/pci-assign-load-rom.c create mode 100644 hw/xen/xen_pt_graphics.c create mode 100644 include/hw/pci/pci-assign.h Thanks Tiejun
[Qemu-devel] [v7][PATCH 01/10] i440fx: make types configurable at run-time
From: Michael S. Tsirkin m...@redhat.com IGD passthrough wants to supply a different pci and host devices, inheriting i440fx devices. Make types configurable. Signed-off-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- hw/i386/pc_piix.c| 4 +++- hw/pci-host/piix.c | 9 - include/hw/i386/pc.h | 6 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 36c69d7..07faec9 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -202,7 +202,9 @@ static void pc_init1(MachineState *machine, } if (pci_enabled) { -pci_bus = i440fx_init(i440fx_state, piix3_devfn, isa_bus, gsi, +pci_bus = i440fx_init(TYPE_I440FX_PCI_HOST_BRIDGE, + TYPE_I440FX_PCI_DEVICE, + i440fx_state, piix3_devfn, isa_bus, gsi, system_memory, system_io, machine-ram_size, below_4g_mem_size, above_4g_mem_size, diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 723836f..c812eaa 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -40,7 +40,6 @@ * http://download.intel.com/design/chipsets/datashts/29054901.pdf */ -#define TYPE_I440FX_PCI_HOST_BRIDGE i440FX-pcihost #define I440FX_PCI_HOST_BRIDGE(obj) \ OBJECT_CHECK(I440FXState, (obj), TYPE_I440FX_PCI_HOST_BRIDGE) @@ -91,7 +90,6 @@ typedef struct PIIX3State { MemoryRegion rcr_mem; } PIIX3State; -#define TYPE_I440FX_PCI_DEVICE i440FX #define I440FX_PCI_DEVICE(obj) \ OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE) @@ -304,7 +302,8 @@ static void i440fx_realize(PCIDevice *dev, Error **errp) cpu_smm_register(i440fx_set_smm, d); } -PCIBus *i440fx_init(PCII440FXState **pi440fx_state, +PCIBus *i440fx_init(const char *host_type, const char *pci_type, +PCII440FXState **pi440fx_state, int *piix3_devfn, ISABus **isa_bus, qemu_irq *pic, MemoryRegion *address_space_mem, @@ -324,7 +323,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, unsigned i; I440FXState *i440fx; -dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE); +dev = qdev_create(NULL, host_type); s = PCI_HOST_BRIDGE(dev); b = pci_bus_new(dev, NULL, pci_address_space, address_space_io, 0, TYPE_PCI_BUS); @@ -332,7 +331,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, object_property_add_child(qdev_get_machine(), i440fx, OBJECT(dev), NULL); qdev_init_nofail(dev); -d = pci_create_simple(b, 0, TYPE_I440FX_PCI_DEVICE); +d = pci_create_simple(b, 0, pci_type); *pi440fx_state = I440FX_PCI_DEVICE(d); f = *pi440fx_state; f-system_memory = address_space_mem; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 1b35168..99dc26b 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -230,7 +230,11 @@ extern int no_hpet; struct PCII440FXState; typedef struct PCII440FXState PCII440FXState; -PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, +#define TYPE_I440FX_PCI_HOST_BRIDGE i440FX-pcihost +#define TYPE_I440FX_PCI_DEVICE i440FX + +PCIBus *i440fx_init(const char *host_type, const char *pci_type, +PCII440FXState **pi440fx_state, int *piix_devfn, ISABus **isa_bus, qemu_irq *pic, MemoryRegion *address_space_mem, MemoryRegion *address_space_io, -- 1.9.1
[Qemu-devel] [v7][PATCH 06/10] xen, gfx passthrough: retrieve VGA BIOS to work
Now we retrieve VGA bios like kvm stuff in qemu but we need to fix Device Identification in case if its not matched with the real IGD device since Seabios is always trying to compare this ID to work out VGA BIOS. Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- hw/xen/xen_pt.c | 10 ++ hw/xen/xen_pt.h | 5 +++ hw/xen/xen_pt_graphics.c | 79 3 files changed, 94 insertions(+) diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index 1d78021..fcc9f1c 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -672,6 +672,16 @@ static int xen_pt_initfn(PCIDevice *d) s-memory_listener = xen_pt_memory_listener; s-io_listener = xen_pt_io_listener; +/* Setup VGA bios for passthrough GFX */ +if ((s-real_device.domain == 0) (s-real_device.bus == 0) +(s-real_device.dev == 2) (s-real_device.func == 0)) { +if (xen_pt_setup_vga(s, s-real_device) 0) { +XEN_PT_ERR(d, Setup VGA BIOS of passthrough GFX failed!\n); +xen_host_pci_device_put(s-real_device); +return -1; +} +} + /* Handle real device's MMIO/PIO BARs */ xen_pt_register_regions(s); diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h index 3325387..d9b1ce0 100644 --- a/hw/xen/xen_pt.h +++ b/hw/xen/xen_pt.h @@ -298,6 +298,11 @@ static inline bool xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar) return s-msix s-msix-bar_index == bar; } +extern void *pci_assign_dev_load_option_rom(PCIDevice *dev, +struct Object *owner, int *size, +unsigned int domain, +unsigned int bus, unsigned int slot, +unsigned int function); extern bool has_igd_gfx_passthru; static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev) { diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c index 9b3df81..3232296 100644 --- a/hw/xen/xen_pt_graphics.c +++ b/hw/xen/xen_pt_graphics.c @@ -109,3 +109,82 @@ int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev) return 0; } + +static void *get_vgabios(XenPCIPassthroughState *s, int *size, + XenHostPCIDevice *dev) +{ +return pci_assign_dev_load_option_rom(s-dev, OBJECT(s-dev), size, + dev-domain, dev-bus, + dev-dev, dev-func); +} + +/* Refer to Seabios. */ +struct rom_header { +uint16_t signature; +uint8_t size; +uint8_t initVector[4]; +uint8_t reserved[17]; +uint16_t pcioffset; +uint16_t pnpoffset; +} __attribute__((packed)); + +struct pci_data { +uint32_t signature; +uint16_t vendor; +uint16_t device; +uint16_t vitaldata; +uint16_t dlen; +uint8_t drevision; +uint8_t class_lo; +uint16_t class_hi; +uint16_t ilen; +uint16_t irevision; +uint8_t type; +uint8_t indicator; +uint16_t reserved; +} __attribute__((packed)); + +int xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev) +{ +unsigned char *bios = NULL; +struct rom_header *rom; +int bios_size; +char *c = NULL; +char checksum = 0; +uint32_t len = 0; +struct pci_data *pd = NULL; + +if (!is_igd_vga_passthrough(dev)) { +return -1; +} + +bios = get_vgabios(s, bios_size, dev); +if (!bios) { +XEN_PT_ERR(s-dev, VGA: Can't getting VBIOS!\n); +return -1; +} + +/* Currently we fixed this address as a primary. */ +rom = (struct rom_header *)bios; +pd = (void *)(bios + (unsigned char)rom-pcioffset); + +/* We may need to fixup Device Identification. */ +if (pd-device != s-real_device.device_id) { +pd-device = s-real_device.device_id; + +len = rom-size * 512; +/* Then adjust the bios checksum */ +for (c = (char *)bios; c ((char *)bios + len); c++) { +checksum += *c; +} +if (checksum) { +bios[len - 1] -= checksum; +XEN_PT_LOG(s-dev, vga bios checksum is adjusted %x!\n, + checksum); +} +} + +/* Currently we fixed this address as a primary for legacy BIOS. */ +cpu_physical_memory_rw(0xc, bios, bios_size, 1); +return 0; +} -- 1.9.1
[Qemu-devel] [PATCH V4 01/19] pc: add 2.4 machine types
The following patches will limit the following things to legacy machine type: - maximum number of virtqueues for virtio-pci were limited to 64 - auto msix bar size for virtio-net-pci were disabled by default Cc: Paolo Bonzini pbonz...@redhat.com Cc: Richard Henderson r...@twiddle.net Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/i386/pc_piix.c | 29 + hw/i386/pc_q35.c | 26 +++--- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 36c69d7..175e582 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -310,8 +310,13 @@ static void pc_init_pci(MachineState *machine) pc_init1(machine, 1, 1); } +static void pc_compat_2_3(MachineState *machine) +{ +} + static void pc_compat_2_2(MachineState *machine) { +pc_compat_2_3(machine); rsdp_in_ram = false; x86_cpu_compat_set_features(kvm64, FEAT_1_EDX, 0, CPUID_VME); x86_cpu_compat_set_features(kvm32, FEAT_1_EDX, 0, CPUID_VME); @@ -417,6 +422,12 @@ static void pc_compat_1_2(MachineState *machine) x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, 1 KVM_FEATURE_PV_EOI); } +static void pc_init_pci_2_3(MachineState *machine) +{ +pc_compat_2_3(machine); +pc_init_pci(machine); +} + static void pc_init_pci_2_2(MachineState *machine) { pc_compat_2_2(machine); @@ -516,19 +527,28 @@ static void pc_xen_hvm_init(MachineState *machine) .desc = Standard PC (i440FX + PIIX, 1996), \ .hot_add_cpu = pc_hot_add_cpu -#define PC_I440FX_2_3_MACHINE_OPTIONS \ +#define PC_I440FX_2_4_MACHINE_OPTIONS \ PC_I440FX_MACHINE_OPTIONS, \ .default_machine_opts = firmware=bios-256k.bin, \ .default_display = std -static QEMUMachine pc_i440fx_machine_v2_3 = { -PC_I440FX_2_3_MACHINE_OPTIONS, -.name = pc-i440fx-2.3, + +static QEMUMachine pc_i440fx_machine_v2_4 = { +PC_I440FX_2_4_MACHINE_OPTIONS, +.name = pc-i440fx-2.4, .alias = pc, .init = pc_init_pci, .is_default = 1, }; +#define PC_I440FX_2_3_MACHINE_OPTIONS PC_I440FX_2_4_MACHINE_OPTIONS + +static QEMUMachine pc_i440fx_machine_v2_3 = { +PC_I440FX_2_3_MACHINE_OPTIONS, +.name = pc-i440fx-2.3, +.init = pc_init_pci_2_3, +}; + #define PC_I440FX_2_2_MACHINE_OPTIONS PC_I440FX_2_3_MACHINE_OPTIONS static QEMUMachine pc_i440fx_machine_v2_2 = { @@ -974,6 +994,7 @@ static QEMUMachine xenfv_machine = { static void pc_machine_init(void) { +qemu_register_pc_machine(pc_i440fx_machine_v2_4); qemu_register_pc_machine(pc_i440fx_machine_v2_3); qemu_register_pc_machine(pc_i440fx_machine_v2_2); qemu_register_pc_machine(pc_i440fx_machine_v2_1); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index bc40537..df44d25 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -289,8 +289,13 @@ static void pc_q35_init(MachineState *machine) } } +static void pc_compat_2_3(MachineState *machine) +{ +} + static void pc_compat_2_2(MachineState *machine) { +pc_compat_2_3(machine); rsdp_in_ram = false; x86_cpu_compat_set_features(kvm64, FEAT_1_EDX, 0, CPUID_VME); x86_cpu_compat_set_features(kvm32, FEAT_1_EDX, 0, CPUID_VME); @@ -365,6 +370,12 @@ static void pc_compat_1_4(MachineState *machine) x86_cpu_compat_set_features(Westmere, FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ); } +static void pc_q35_init_2_3(MachineState *machine) +{ +pc_compat_2_3(machine); +pc_q35_init(machine); +} + static void pc_q35_init_2_2(MachineState *machine) { pc_compat_2_2(machine); @@ -414,16 +425,24 @@ static void pc_q35_init_1_4(MachineState *machine) .hot_add_cpu = pc_hot_add_cpu, \ .units_per_default_bus = 1 -#define PC_Q35_2_3_MACHINE_OPTIONS \ +#define PC_Q35_2_4_MACHINE_OPTIONS \ PC_Q35_MACHINE_OPTIONS, \ .default_machine_opts = firmware=bios-256k.bin, \ .default_display = std +static QEMUMachine pc_q35_machine_v2_4 = { +PC_Q35_2_4_MACHINE_OPTIONS, +.name = pc-q35-2.4, +.alias = q35, +.init = pc_q35_init, +}; + +#define PC_Q35_2_3_MACHINE_OPTIONS PC_Q35_2_4_MACHINE_OPTIONS + static QEMUMachine pc_q35_machine_v2_3 = { PC_Q35_2_3_MACHINE_OPTIONS, .name = pc-q35-2.3, -.alias = q35, -.init = pc_q35_init, +.init = pc_q35_init_2_3, }; #define PC_Q35_2_2_MACHINE_OPTIONS PC_Q35_2_3_MACHINE_OPTIONS @@ -510,6 +529,7 @@ static QEMUMachine pc_q35_machine_v1_4 = { static void pc_q35_machine_init(void) { +qemu_register_pc_machine(pc_q35_machine_v2_4); qemu_register_pc_machine(pc_q35_machine_v2_3); qemu_register_pc_machine(pc_q35_machine_v2_2); qemu_register_pc_machine(pc_q35_machine_v2_1); -- 2.1.0
[Qemu-devel] [PATCH V4 13/19] virtio-pci: switch to use bus specific queue limit
Instead of depending on a macro, switch to use a bus specific queue limit. Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/virtio/virtio-pci.c | 12 +++- include/hw/virtio/virtio.h | 2 -- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 075b13b..e556919 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -42,6 +42,8 @@ * configuration space */ #define VIRTIO_PCI_CONFIG_SIZE(dev) VIRTIO_PCI_CONFIG_OFF(msix_enabled(dev)) +#define VIRTIO_PCI_QUEUE_MAX 64 + static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size, VirtIOPCIProxy *dev); @@ -171,7 +173,7 @@ static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy) return; } -for (n = 0; n VIRTIO_PCI_QUEUE_MAX; n++) { +for (n = 0; n virtio_get_queue_max(vdev); n++) { if (!virtio_queue_get_num(vdev, n)) { continue; } @@ -207,7 +209,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy) return; } -for (n = 0; n VIRTIO_PCI_QUEUE_MAX; n++) { +for (n = 0; n virtio_get_queue_max(vdev); n++) { if (!virtio_queue_get_num(vdev, n)) { continue; } @@ -243,11 +245,11 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) virtio_queue_set_addr(vdev, vdev-queue_sel, pa); break; case VIRTIO_PCI_QUEUE_SEL: -if (val VIRTIO_PCI_QUEUE_MAX) +if (val virtio_get_queue_max(vdev)) vdev-queue_sel = val; break; case VIRTIO_PCI_QUEUE_NOTIFY: -if (val VIRTIO_PCI_QUEUE_MAX) { +if (val virtio_get_queue_max(vdev)) { virtio_queue_notify(vdev, val); } break; @@ -748,7 +750,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) bool with_irqfd = msix_enabled(proxy-pci_dev) kvm_msi_via_irqfd_enabled(); -nvqs = MIN(nvqs, VIRTIO_PCI_QUEUE_MAX); +nvqs = MIN(nvqs, virtio_get_queue_max(vdev)); /* When deassigning, pass a consistent nvqs value * to avoid leaking notifiers. diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 91fd673..7ff40ac 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -48,8 +48,6 @@ typedef struct VirtQueueElement struct iovec out_sg[VIRTQUEUE_MAX_SIZE]; } VirtQueueElement; -#define VIRTIO_PCI_QUEUE_MAX 64 - #define VIRTIO_NO_VECTOR 0x #define TYPE_VIRTIO_DEVICE virtio-device -- 2.1.0
[Qemu-devel] [PATCH v4 2/3] ehci: fix segfault when hot-unplugging ehci controller
From: Gonglei arei.gong...@huawei.com When hot-unplugging the usb controllers (ehci/uhci), we have to clean all resouce of these devices, involved registered reset handler. Otherwise, it may cause NULL pointer access and/or segmentation fault if we reboot the guest os after hot-unplugging. Let's hook up reset via DeviceClass-reset() and drop the qemu_register_reset() call. Then Qemu will register and unregister the reset handler automatically. Cc: qemu-stable qemu-sta...@nongnu.org Reported-by: Lidonglin lidong...@huawei.com Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/usb/hcd-ehci-pci.c| 10 ++ hw/usb/hcd-ehci-sysbus.c | 10 ++ hw/usb/hcd-ehci.c| 3 +-- hw/usb/hcd-ehci.h| 1 + 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c index 4c80707..7afa5f9 100644 --- a/hw/usb/hcd-ehci-pci.c +++ b/hw/usb/hcd-ehci-pci.c @@ -101,6 +101,15 @@ static void usb_ehci_pci_exit(PCIDevice *dev) } } +static void usb_ehci_pci_reset(DeviceState *dev) +{ +PCIDevice *pci_dev = PCI_DEVICE(dev); +EHCIPCIState *i = PCI_EHCI(pci_dev); +EHCIState *s = i-ehci; + +ehci_reset(s); +} + static void usb_ehci_pci_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int l) { @@ -143,6 +152,7 @@ static void ehci_class_init(ObjectClass *klass, void *data) k-config_write = usb_ehci_pci_write_config; dc-vmsd = vmstate_ehci_pci; dc-props = ehci_pci_properties; +dc-reset = usb_ehci_pci_reset; } static const TypeInfo ehci_pci_type_info = { diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c index 19ed2c2..cd1cc14 100644 --- a/hw/usb/hcd-ehci-sysbus.c +++ b/hw/usb/hcd-ehci-sysbus.c @@ -42,6 +42,15 @@ static void usb_ehci_sysbus_realize(DeviceState *dev, Error **errp) sysbus_init_irq(d, s-irq); } +static void usb_ehci_sysbus_reset(DeviceState *dev) +{ +SysBusDevice *d = SYS_BUS_DEVICE(dev); +EHCISysBusState *i = SYS_BUS_EHCI(d); +EHCIState *s = i-ehci; + +ehci_reset(s); +} + static void ehci_sysbus_init(Object *obj) { SysBusDevice *d = SYS_BUS_DEVICE(obj); @@ -70,6 +79,7 @@ static void ehci_sysbus_class_init(ObjectClass *klass, void *data) dc-realize = usb_ehci_sysbus_realize; dc-vmsd = vmstate_ehci_sysbus; dc-props = ehci_sysbus_properties; +dc-reset = usb_ehci_sysbus_reset; set_bit(DEVICE_CATEGORY_USB, dc-categories); } diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index ccf54b6..2a84f46 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -845,7 +845,7 @@ static USBDevice *ehci_find_device(EHCIState *ehci, uint8_t addr) } /* 4.1 host controller initialization */ -static void ehci_reset(void *opaque) +void ehci_reset(void *opaque) { EHCIState *s = opaque; int i; @@ -2471,7 +2471,6 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) s-async_bh = qemu_bh_new(ehci_frame_timer, s); s-device = dev; -qemu_register_reset(ehci_reset, s); s-vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s); } diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index 2bc259c..87b240f 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -325,6 +325,7 @@ extern const VMStateDescription vmstate_ehci; void usb_ehci_init(EHCIState *s, DeviceState *dev); void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp); void usb_ehci_unrealize(EHCIState *s, DeviceState *dev, Error **errp); +void ehci_reset(void *opaque); #define TYPE_PCI_EHCI pci-ehci-usb #define PCI_EHCI(obj) OBJECT_CHECK(EHCIPCIState, (obj), TYPE_PCI_EHCI) -- 1.7.12.4
Re: [Qemu-devel] [v2][PATCH 2/2] libxl: introduce gfx_passthru_kind
On Wed, 2015-03-18 at 15:32 +0800, Chen, Tiejun wrote: I think the _libxl_ message needs to be just Unable to detect graphics passthru kind. i.e. it can't/shouldn't reference anything to do with xl config options etc (which would make no sense if libvirt was being used). That's not very user friendly though, so you may want to consider adding a new specific error code for this case and returning it here, such that xl or libvirt can then give a more comprehensible error message. But, args = libxl__build_device_model_args(gc, stubdom-dm, guest_domid, guest_config, d_state, NULL); | + return libxl__build_device_model_args_new(gc, dm,guest_domid, guest_config, state, dm_state_fd); | + Currently we always return NULL inside. if (!args) { ret = ERROR_FAIL; goto out; } So I'm not very sure how to pass this new specific error code to xl/libvirt. Bah, yes. I don't think it is reasonable to ask you to rework the error handling here completely for this. Lets leave this as a potential future enhancement. Thanks but I guess I'd better to paste this whole patch to avoid I'm still missing something :) --- tools/libxl/libxl.h | 6 ++ tools/libxl/libxl_dm.c | 25 ++--- tools/libxl/libxl_internal.h | 5 + tools/libxl/libxl_types.idl | 6 ++ tools/libxl/xl_cmdimpl.c | 14 -- 5 files changed, 51 insertions(+), 5 deletions(-) diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index 6bbc52d..62b3ae5 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -720,6 +720,12 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src); #define LIBXL_HAVE_PSR_MBM 1 #endif +/* + * libxl_domain_build_info has the u.hvm.gfx_passthru_kind field and + * the libxl_gfx_passthru_kind enumeration is defined. +*/ +#define LIBXL_HAVE_GFX_PASSTHRU_KIND + typedef char **libxl_string_list; void libxl_string_list_dispose(libxl_string_list *sl); int libxl_string_list_length(const libxl_string_list *sl); diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c index 8599a6a..045d48a 100644 --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -710,9 +710,6 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc, flexarray_append(dm_args, -net); flexarray_append(dm_args, none); } -if (libxl_defbool_val(b_info-u.hvm.gfx_passthru)) { -flexarray_append(dm_args, -gfx_passthru); -} } else { if (!sdl !vnc) { flexarray_append(dm_args, -nographic); @@ -757,6 +754,28 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc, machinearg, max_ram_below_4g); } } + +if (libxl_defbool_val(b_info-u.hvm.gfx_passthru)) { +switch (b_info-u.hvm.gfx_passthru_kind) { +case _info-u.hvm.gfx_passthru_kind: +if (libxl__is_igd_vga_passthru(gc, guest_config)) { +machinearg = GCSPRINTF(%s,igd-passthru=on, machinearg); +} else { +LOG(ERROR, Unable to detect graphics passthru kind, + please set gfx_passthru_kind. See xl.cfg(5) for more + information.\n); Please change this to Unable to detect graphics passthru kind to avoid talking xl-isms in libxl. +return NULL; +} +break; +case LIBXL_GFX_PASSTHRU_KIND_IGD: +machinearg = GCSPRINTF(%s,igd-passthru=on, machinearg); +break; This duplicates the code from above. I think this would be best done as: static int libxl__detect_gfx_passthru_kind(libxl__gc *gc, guest_config) { if (b_info-u.hvm.gfx_passthru_kind != LIBXL_GFX_PASSTHRU_KIND_DEFAULT) return 0; if (libxl__is_igd_vga_passthru(gc, guest_config)) { b_info-u.hvm.gfx_passthru_kind = LIBXL_GFX_PASSTHRU_KIND_IGD; return 0; } LOG(ERROR, Unable to detect graphics passthru kind); return 1; } Then for the code in libxl__build_device_model_args_new: if (libxl_defbool_val(b_info-u.hvm.gfx_passthru)) { if (!libxl__detect_gfx_passthru_kind(gc, guest_config)) return NULL switch (b_info-u.hvm.gfx_passthru_kind) { case LIBXL_GFX_PASSTHRU_KIND_IGD: machinearg = GCSPRINTF(%s,igd-passthru=on, machinearg); break; default: LOG(ERROR, unknown gfx_passthru_kind\n); return NULL; } } That is, a helper to try and autodetect kind if it is default and then a single switch entry for each kind. +default: +
[Qemu-devel] [PULL 06/19] nbd: Handle blk_getlength() failure
From: Max Reitz mre...@redhat.com Signed-off-by: Max Reitz mre...@redhat.com Message-Id: 1424887718-10800-9-git-send-email-mre...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- blockdev-nbd.c | 6 +- include/block/nbd.h | 3 ++- nbd.c | 16 ++-- qemu-nbd.c | 10 +- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 22e95d1..b29e456 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -105,7 +105,11 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable, writable = false; } -exp = nbd_export_new(blk, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY, NULL); +exp = nbd_export_new(blk, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY, NULL, + errp); +if (!exp) { +return; +} nbd_export_set_name(exp, device); diff --git a/include/block/nbd.h b/include/block/nbd.h index ca9a5ac..2c20138 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -86,7 +86,8 @@ typedef struct NBDExport NBDExport; typedef struct NBDClient NBDClient; NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size, - uint32_t nbdflags, void (*close)(NBDExport *)); + uint32_t nbdflags, void (*close)(NBDExport *), + Error **errp); void nbd_export_close(NBDExport *exp); void nbd_export_get(NBDExport *exp); void nbd_export_put(NBDExport *exp); diff --git a/nbd.c b/nbd.c index 34f4dbb..8837e75 100644 --- a/nbd.c +++ b/nbd.c @@ -966,7 +966,8 @@ static void blk_aio_detach(void *opaque) } NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size, - uint32_t nbdflags, void (*close)(NBDExport *)) + uint32_t nbdflags, void (*close)(NBDExport *), + Error **errp) { NBDExport *exp = g_malloc0(sizeof(NBDExport)); exp-refcount = 1; @@ -974,7 +975,14 @@ NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size, exp-blk = blk; exp-dev_offset = dev_offset; exp-nbdflags = nbdflags; -exp-size = size == -1 ? blk_getlength(blk) : size; +exp-size = size 0 ? blk_getlength(blk) : size; +if (exp-size 0) { +error_setg_errno(errp, -exp-size, + Failed to determine the NBD export's length); +goto fail; +} +exp-size -= exp-size % BDRV_SECTOR_SIZE; + exp-close = close; exp-ctx = blk_get_aio_context(blk); blk_ref(blk); @@ -986,6 +994,10 @@ NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size, */ blk_invalidate_cache(blk, NULL); return exp; + +fail: +g_free(exp); +return NULL; } NBDExport *nbd_export_find(const char *name) diff --git a/qemu-nbd.c b/qemu-nbd.c index d8daf1d..0cb0e4e 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -717,6 +717,10 @@ int main(int argc, char **argv) bs-detect_zeroes = detect_zeroes; fd_size = blk_getlength(blk); +if (fd_size 0) { +errx(EXIT_FAILURE, Failed to determine the image length: %s, + strerror(-fd_size)); +} if (partition != -1) { ret = find_partition(blk, partition, dev_offset, fd_size); @@ -726,7 +730,11 @@ int main(int argc, char **argv) } } -exp = nbd_export_new(blk, dev_offset, fd_size, nbdflags, nbd_export_closed); +exp = nbd_export_new(blk, dev_offset, fd_size, nbdflags, nbd_export_closed, + local_err); +if (!exp) { +errx(EXIT_FAILURE, %s, error_get_pretty(local_err)); +} if (sockpath) { fd = unix_socket_incoming(sockpath); -- 2.3.0
[Qemu-devel] [PULL 03/19] qemu-nbd: Detect unused partitions by system == 0
From: Max Reitz mre...@redhat.com Unused partitions do not necessarily have a total sector count of 0 (although they should have), but they always do have the system field set to 0, so use that for testing whether a partition is in use rather than the sector count field alone. Signed-off-by: Max Reitz mre...@redhat.com Message-Id: 1424887718-10800-3-git-send-email-mre...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- qemu-nbd.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qemu-nbd.c b/qemu-nbd.c index 064b000..d8daf1d 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -167,8 +167,9 @@ static int find_partition(BlockBackend *blk, int partition, for (i = 0; i 4; i++) { read_partition(data[446 + 16 * i], mbr[i]); -if (!mbr[i].nb_sectors_abs) +if (!mbr[i].system || !mbr[i].nb_sectors_abs) { continue; +} if (mbr[i].system == 0xF || mbr[i].system == 0x5) { struct partition_record ext[4]; @@ -182,8 +183,9 @@ static int find_partition(BlockBackend *blk, int partition, for (j = 0; j 4; j++) { read_partition(data1[446 + 16 * j], ext[j]); -if (!ext[j].nb_sectors_abs) +if (!ext[j].system || !ext[j].nb_sectors_abs) { continue; +} if ((ext_partnum + j + 1) == partition) { *offset = (uint64_t)ext[j].start_sector_abs 9; -- 2.3.0
[Qemu-devel] [PULL 01/19] nbd: Fix overflow return value
From: Yik Fang eric.fan...@huawei.com The value of reply.error should be the type unsigned int. Signed-off-by: Yik Fang eric.fan...@huawei.com Message-Id: 1423722111-12902-1-git-send-email-eric.fan...@huawei.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- nbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nbd.c b/nbd.c index 71159af..02ba0fe 100644 --- a/nbd.c +++ b/nbd.c @@ -1295,7 +1295,7 @@ static void nbd_trip(void *opaque) default: LOG(invalid request type (%u) received, request.type); invalid_request: -reply.error = -EINVAL; +reply.error = EINVAL; error_reply: if (nbd_co_send_reply(req, reply, 0) 0) { goto out; -- 2.3.0
Re: [Qemu-devel] [PATCH v3 1/3] uhci: fix segfault when hot-unplugging uhci controller
On 2015/3/18 15:35, Markus Armbruster wrote: Gerd Hoffmann kra...@redhat.com writes: Hi, -static void uhci_reset(void *opaque) +static void uhci_reset(DeviceState *dev) { -UHCIState *s = opaque; +PCIDevice *d = PCI_DEVICE(dev); +UHCIState *s = DO_UPCAST(UHCIState, dev, d); Uh, oh, DO_UPCAST() is long deprecated. There are other instances of [...] Only 378 instances left in the code %-} Maybe I can do some cleanup work for 2.4 ;) Regards, -Gonglei
[Qemu-devel] [PATCH V4 02/19] spapr: add machine type specific instance init function
This patches adds machine type specific instance initialization functions. Those functions will be used by following patches to compat class properties for legacy machine types. Cc: Alexander Graf ag...@suse.de Cc: qemu-...@nongnu.org Signed-off-by: Jason Wang jasow...@redhat.com --- hw/ppc/spapr.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0487f52..7fb174f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1803,6 +1803,27 @@ static const TypeInfo spapr_machine_info = { #define SPAPR_COMPAT_2_1 \ SPAPR_COMPAT_2_2 +static void spapr_compat_2_2(Object *obj) +{ +} + +static void spapr_compat_2_1(Object *obj) +{ +spapr_compat_2_2(obj); +} + +static void spapr_machine_2_2_instance_init(Object *obj) +{ +spapr_compat_2_2(obj); +spapr_machine_initfn(obj); +} + +static void spapr_machine_2_1_instance_init(Object *obj) +{ +spapr_compat_2_1(obj); +spapr_machine_initfn(obj); +} + static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -1821,6 +1842,7 @@ static const TypeInfo spapr_machine_2_1_info = { .name = TYPE_SPAPR_MACHINE 2.1, .parent= TYPE_SPAPR_MACHINE, .class_init= spapr_machine_2_1_class_init, +.instance_init = spapr_machine_2_1_instance_init, }; static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data) @@ -1840,6 +1862,7 @@ static const TypeInfo spapr_machine_2_2_info = { .name = TYPE_SPAPR_MACHINE 2.2, .parent= TYPE_SPAPR_MACHINE, .class_init= spapr_machine_2_2_class_init, +.instance_init = spapr_machine_2_2_instance_init, }; static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data) -- 2.1.0
[Qemu-devel] [PATCH V4 00/19] Support more virtio queues
We current limit the max virtio queues to 64. This is not sufficient to support multiqueue devices (e.g recent Linux support up to 256 tap queues). So this series tries to let virtio to support more queues. No much works need to be done except: - Introducing transport specific queue limitation. - Let each virtio transport to use specific limit. - Speedup the MSI-X masking and unmasking through per vector queue list, and increase the maximum MSI-X vectors supported by qemu. - With the above enhancements, increase the maximum number of virtqueues supported by PCI from 64 to 513. - Compat the changes for legacy machine types. With this patch, we can support up to 256 queues. Since x86 can only allow about 240 interrupt vectors for MSI-X, current Linux driver can only have about 80 queue pairs has their private MSI-X interrupt vectors. With sharing IRQ with queue pairs (RFC posted in https://lkml.org/lkml/2014/12/25/169), Linux driver can have up to about 186 queue pairs has their private MSI-X interrupt vectors. Stress/migration test on virtio-pci, compile test on other targets. And make check on s390x-softmmu and ppc64-softmmu. Cc: Paolo Bonzini pbonz...@redhat.com Cc: Richard Henderson r...@twiddle.net Cc: Michael S. Tsirkin m...@redhat.com Cc: Alexander Graf ag...@suse.de Cc: Keith Busch keith.bu...@intel.com Cc: Kevin Wolf kw...@redhat.com Cc: Stefan Hajnoczi stefa...@redhat.com Cc: Christian Borntraeger borntrae...@de.ibm.com Cc: Cornelia Huck cornelia.h...@de.ibm.com Cc: Amit Shah amit.s...@redhat.com Cc: qemu-...@nongnu.org Please review Thanks Changes from V3: - rebase to master and target to 2.4 - handling compat issues for spapr - fixes for hmp command completion when we have a nic with 256 queues - using VIRTIO_NO_VECTOR instead of 0 for invalid virtqueue in virtio-ccw - fix compile issues for ppc64-softmmu - don't export VIRTIO_CCW_QUEUE_MAX by introducing a gsi limit and inherit in ccw - use transport specific queue limit in virtio-serial - correct the stale comment for AdapterRoutes and move it to ccw patch - replace 128 with queue_max + 64 and add a comment for this in virtio_ccw_notify() Changes from V2: - move transport specific limitation to their implementation. (The left is VIRTIO_CCW_QUEUE_MAX since I fail to find a common header files other than virtio.h) - use virtio_get_queue_max() if possible in virtio.c - AdapterRoutes should use ccw limit - introduce a vector to queue mapping for virito devices and speedup the MSI-X masking and unmasking through this. Changes from V1: - add a validation against the bus limitation - switch to use a bus specific queue limit instead of a global one, this will allow us to just increase the limit of one transport without disturbing others. - only increase the queue limit of virtio-pci - limit the maximum number of virtio queues to 64 for legacy machine types Jason Wang (19): pc: add 2.4 machine types spapr: add machine type specific instance init function ppc: spapr: add 2.4 machine type monitor: replace the magic number 255 with MAX_QUEUE_NUM monitor: check return value of qemu_find_net_clients_except() virtio-ccw: using VIRTIO_NO_VECTOR instead of 0 for invalid virtqueue virtio-net: validate backend queue numbers against bus limitation virtio-net: fix the upper bound when trying to delete queues virito: introduce bus specific queue limit virtio-ccw: introduce ccw specific queue limit virtio-s390: switch to bus specific queue limit virtio-mmio: switch to bus specific queue limit virtio-pci: switch to use bus specific queue limit virtio: introduce vector to virtqueues mapping virtio: introduce virtio_queue_get_index() virtio-pci: speedup MSI-X masking and unmasking virtio-pci: increase the maximum number of virtqueues to 513 pci: remove hard-coded bar size in msix_init_exclusive_bar() virtio-pci: introduce auto_msix_bar_size property hw/block/nvme.c| 2 +- hw/char/virtio-serial-bus.c| 2 +- hw/i386/pc_piix.c | 42 --- hw/i386/pc_q35.c | 39 +++-- hw/misc/ivshmem.c | 2 +- hw/net/virtio-net.c| 9 - hw/pci/msix.c | 18 -- hw/ppc/spapr.c | 70 +++-- hw/s390x/s390-virtio-bus.c | 7 ++-- hw/s390x/s390-virtio-ccw.c | 7 ++-- hw/s390x/virtio-ccw.c | 20 +++ hw/scsi/virtio-scsi.c | 4 +-- hw/virtio/virtio-mmio.c| 7 ++-- hw/virtio/virtio-pci.c | 78 -- hw/virtio/virtio-pci.h | 3 ++ hw/virtio/virtio.c | 75 +++- include/hw/compat.h| 11 ++ include/hw/pci/msix.h | 2 +- include/hw/s390x/s390_flic.h | 4 ++- include/hw/virtio/virtio-bus.h | 2 ++ include/hw/virtio/virtio.h | 7 ++-- monitor.c | 25
Re: [Qemu-devel] [PATCH v3 2/3] ehci: fix segfault when hot-unplugging ehci controller
On Mi, 2015-03-18 at 09:49 +0800, arei.gong...@huawei.com wrote: From: Gonglei arei.gong...@huawei.com When hot-unplugging the usb controllers (ehci/uhci), we have to clean all resouce of these devices, involved registered reset handler. Otherwise, it may cause NULL pointer access and/or segmentation fault if we reboot the guest os after hot-unplugging. Let's hook up reset via DeviceClass-reset() and drop the qemu_register_reset() call. Then Qemu will register and unregister the reset handler automatically. Fails make check (for aarch64). My guess is the sysbus variants lost the reset hookup. cheers, Gerd
[Qemu-devel] [v7][PATCH 09/10] xen, gfx passthrough: register host bridge specific to passthrough
Just register that pci host bridge specific to passthrough. Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- hw/i386/pc_piix.c | 19 +-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 8fbfc09..eae2d20 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -50,7 +50,8 @@ #include cpu.h #include qemu/error-report.h #ifdef CONFIG_XEN -# include xen/hvm/hvm_info_table.h +#include xen/hvm/hvm_info_table.h +#include hw/xen/xen_pt.h #endif #define MAX_IDE_BUS 2 @@ -504,11 +505,25 @@ static void pc_init_isa(MachineState *machine) } #ifdef CONFIG_XEN +static void igd_passthrough_pc_init_pci(MachineState *machine) +{ +pc_init1(machine, 1, 1, TYPE_I440FX_PCI_HOST_BRIDGE, + TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE); +} + +static void pc_igd_init_pci(MachineState *machine) +{ +if (has_igd_gfx_passthru) +igd_passthrough_pc_init_pci(machine); +else +pc_init_pci(machine); +} + static void pc_xen_hvm_init(MachineState *machine) { PCIBus *bus; -pc_init_pci(machine); +pc_igd_init_pci(machine); bus = pci_find_primary_bus(); if (bus != NULL) { -- 1.9.1
[Qemu-devel] [v7][PATCH 04/10] hw/pci-assign: split pci-assign.c
We will try to reuse assign_dev_load_option_rom in xen side, and especially its a good beginning to unify pci assign codes both on kvm and xen in the future. Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- hw/i386/Makefile.objs | 1 + hw/i386/kvm/pci-assign.c | 82 -- hw/i386/pci-assign-load-rom.c | 93 +++ include/hw/pci/pci-assign.h | 27 + 4 files changed, 128 insertions(+), 75 deletions(-) create mode 100644 hw/i386/pci-assign-load-rom.c create mode 100644 include/hw/pci/pci-assign.h diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index e058a39..8bd1932 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -7,6 +7,7 @@ obj-$(CONFIG_XEN) += ../xenpv/ xen/ obj-y += kvmvapic.o obj-y += acpi-build.o +obj-y += pci-assign-load-rom.o hw/i386/acpi-build.o: hw/i386/acpi-build.c \ hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \ hw/i386/ssdt-tpm.hex diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index 9db7c77..fe870c9 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -37,6 +37,7 @@ #include hw/pci/pci.h #include hw/pci/msi.h #include kvm_i386.h +#include hw/pci/pci-assign.h #define MSIX_PAGE_SIZE 0x1000 @@ -48,17 +49,6 @@ #define IORESOURCE_PREFETCH 0x2000 /* No side effects */ #define IORESOURCE_MEM_64 0x0010 -//#define DEVICE_ASSIGNMENT_DEBUG - -#ifdef DEVICE_ASSIGNMENT_DEBUG -#define DEBUG(fmt, ...) \ -do { \ -fprintf(stderr, %s: fmt, __func__ , __VA_ARGS__); \ -} while (0) -#else -#define DEBUG(fmt, ...) -#endif - typedef struct PCIRegion { int type; /* Memory or port I/O */ int valid; @@ -1893,73 +1883,15 @@ static void assign_register_types(void) type_init(assign_register_types) -/* - * Scan the assigned devices for the devices that have an option ROM, and then - * load the corresponding ROM data to RAM. If an error occurs while loading an - * option ROM, we just ignore that option ROM and continue with the next one. - */ static void assigned_dev_load_option_rom(AssignedDevice *dev) { -char name[32], rom_file[64]; -FILE *fp; -uint8_t val; -struct stat st; -void *ptr; - -/* If loading ROM from file, pci handles it */ -if (dev-dev.romfile || !dev-dev.rom_bar) { -return; -} +int size = 0; -snprintf(rom_file, sizeof(rom_file), - /sys/bus/pci/devices/%04x:%02x:%02x.%01x/rom, - dev-host.domain, dev-host.bus, dev-host.slot, - dev-host.function); +pci_assign_dev_load_option_rom(dev-dev, OBJECT(dev), size, + dev-host.domain, dev-host.bus, + dev-host.slot, dev-host.function); -if (stat(rom_file, st)) { -return; -} - -if (access(rom_file, F_OK)) { -error_report(pci-assign: Insufficient privileges for %s, rom_file); -return; -} - -/* Write 1 to the ROM file to enable it */ -fp = fopen(rom_file, r+); -if (fp == NULL) { -return; +if (!size) { +error_report(pci-assign: Invalid ROM.); } -val = 1; -if (fwrite(val, 1, 1, fp) != 1) { -goto close_rom; -} -fseek(fp, 0, SEEK_SET); - -snprintf(name, sizeof(name), %s.rom, -object_get_typename(OBJECT(dev))); -memory_region_init_ram(dev-dev.rom, OBJECT(dev), name, st.st_size, - error_abort); -vmstate_register_ram(dev-dev.rom, dev-dev.qdev); -ptr = memory_region_get_ram_ptr(dev-dev.rom); -memset(ptr, 0xff, st.st_size); - -if (!fread(ptr, 1, st.st_size, fp)) { -error_report(pci-assign: Cannot read from host %s, rom_file); -error_printf(Device option ROM contents are probably invalid - (check dmesg).\nSkip option ROM probe with rombar=0, - or load from file with romfile=\n); -goto close_rom; -} - -pci_register_bar(dev-dev, PCI_ROM_SLOT, 0, dev-dev.rom); -dev-dev.has_rom = true; -close_rom: -/* Write 0 to disable ROM */ -fseek(fp, 0, SEEK_SET); -val = 0; -if (!fwrite(val, 1, 1, fp)) { -DEBUG(%s\n, Failed to disable pci-sysfs rom file); -} -fclose(fp); } diff --git a/hw/i386/pci-assign-load-rom.c b/hw/i386/pci-assign-load-rom.c new file mode 100644 index 000..a04b540 --- /dev/null +++ b/hw/i386/pci-assign-load-rom.c @@ -0,0 +1,93 @@ +/* + * This is splited from hw/i386/kvm/pci-assign.c + */ +#include stdio.h +#include unistd.h +#include sys/io.h +#include sys/mman.h +#include sys/types.h +#include sys/stat.h +#include hw/hw.h +#include hw/i386/pc.h +#include qemu/error-report.h +#include ui/console.h +#include hw/loader.h +#include monitor/monitor.h +#include qemu/range.h +#include sysemu/sysemu.h
[Qemu-devel] [PATCH V4 14/19] virtio: introduce vector to virtqueues mapping
Currently we will try to traverse all virtqueues to find a subset that using a specific vector. This is sub optimal when we will support hundreds or even thousands of virtqueues. So this patch introduces a method which could be used by transport to get all virtqueues that using a same vector. This is done through QLISTs and the number of QLISTs was queried through a transport specific method. When guest setting vectors, the virtqueue will be linked and helpers for traverse the list was also introduced. The first user will be virtio pci which will use this to speed up MSI-X masking and unmasking handling. Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/virtio/virtio-pci.c | 8 hw/virtio/virtio.c | 32 ++-- include/hw/virtio/virtio-bus.h | 1 + include/hw/virtio/virtio.h | 3 +++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index e556919..c38f33f 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -910,6 +910,13 @@ static const TypeInfo virtio_9p_pci_info = { * virtio-pci: This is the PCIDevice which has a virtio-pci-bus. */ +static int virtio_pci_query_nvectors(DeviceState *d) +{ +VirtIOPCIProxy *proxy = VIRTIO_PCI(d); + +return proxy-nvectors; +} + /* This is called by virtio-bus just after the device is plugged. */ static void virtio_pci_device_plugged(DeviceState *d) { @@ -1500,6 +1507,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data) k-vmstate_change = virtio_pci_vmstate_change; k-device_plugged = virtio_pci_device_plugged; k-device_unplugged = virtio_pci_device_unplugged; +k-query_nvectors = virtio_pci_query_nvectors; k-queue_max = VIRTIO_PCI_QUEUE_MAX; } diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 023eb04..ca157e8 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -89,6 +89,7 @@ struct VirtQueue VirtIODevice *vdev; EventNotifier guest_notifier; EventNotifier host_notifier; +QLIST_ENTRY(VirtQueue) node; }; /* virt queue functions */ @@ -613,7 +614,7 @@ void virtio_reset(void *opaque) vdev-vq[i].vring.used = 0; vdev-vq[i].last_avail_idx = 0; vdev-vq[i].pa = 0; -vdev-vq[i].vector = VIRTIO_NO_VECTOR; +virtio_queue_set_vector(vdev, i, VIRTIO_NO_VECTOR); vdev-vq[i].signalled_used = 0; vdev-vq[i].signalled_used_valid = false; vdev-vq[i].notification = true; @@ -738,6 +739,16 @@ void virtio_queue_set_num(VirtIODevice *vdev, int n, int num) virtqueue_init(vdev-vq[n]); } +VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector) +{ +return QLIST_FIRST(vdev-vector_queues[vector]); +} + +VirtQueue *virtio_vector_next_queue(VirtQueue *vq) +{ +return QLIST_NEXT(vq, node); +} + int virtio_queue_get_num(VirtIODevice *vdev, int n) { return vdev-vq[n].vring.num; @@ -788,8 +799,17 @@ uint16_t virtio_queue_vector(VirtIODevice *vdev, int n) void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector) { -if (n virtio_get_queue_max(vdev)) +VirtQueue *vq = vdev-vq[n]; + +if (n virtio_get_queue_max(vdev)) { +if (vdev-vq[n].vector != VIRTIO_NO_VECTOR) { +QLIST_REMOVE(vq, node); +} vdev-vq[n].vector = vector; +if (vector != VIRTIO_NO_VECTOR) { +QLIST_INSERT_HEAD(vdev-vector_queues[vector], vq, node); +} +} } VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, @@ -1097,6 +1117,7 @@ void virtio_cleanup(VirtIODevice *vdev) qemu_del_vm_change_state_handler(vdev-vmstate); g_free(vdev-config); g_free(vdev-vq); +g_free(vdev-vector_queues); } static void virtio_vmstate_change(void *opaque, int running, RunState state) @@ -1134,7 +1155,14 @@ void virtio_instance_init_common(Object *proxy_obj, void *data, void virtio_init(VirtIODevice *vdev, const char *name, uint16_t device_id, size_t config_size) { +BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); +VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); int i, queue_max = virtio_get_queue_max(vdev); +int nvectors = k-query_nvectors ? +k-query_nvectors(qbus-parent) : queue_max; + +vdev-vector_queues = g_malloc0(sizeof(*vdev-vector_queues) * nvectors); + vdev-device_id = device_id; vdev-status = 0; vdev-isr = 0; diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h index 4da8022..12386d5 100644 --- a/include/hw/virtio/virtio-bus.h +++ b/include/hw/virtio/virtio-bus.h @@ -62,6 +62,7 @@ typedef struct VirtioBusClass { * This is called by virtio-bus just before the device is unplugged. */ void (*device_unplugged)(DeviceState *d); +int (*query_nvectors)(DeviceState *d); /* * Does the transport have variable vring alignment?
[Qemu-devel] [PATCH V4 07/19] virtio-net: validate backend queue numbers against bus limitation
We don't validate the backend queue numbers against bus limitation, this will easily crash qemu if it exceeds the limitation. Fixing this by doing the validation and fail early. Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/net/virtio-net.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 27adcc5..59f76bc 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1588,6 +1588,13 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) virtio_init(vdev, virtio-net, VIRTIO_ID_NET, n-config_size); n-max_queues = MAX(n-nic_conf.peers.queues, 1); +if (n-max_queues * 2 + 1 VIRTIO_PCI_QUEUE_MAX) { +error_setg(errp, Invalid number of queues (= % PRIu32 ), + must be a postive integer less than %d., + n-max_queues, (VIRTIO_PCI_QUEUE_MAX - 1) / 2); +virtio_cleanup(vdev); +return; +} n-vqs = g_malloc0(sizeof(VirtIONetQueue) * n-max_queues); n-vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx); n-curr_queues = 1; -- 2.1.0
[Qemu-devel] [PATCH V4 18/19] pci: remove hard-coded bar size in msix_init_exclusive_bar()
This patch let msix_init_exclusive_bar() can accept bar_size parameter other than a hard-coded limit 4096. Then caller can specify a bar_size depends on msix entries and can use up to 2048 msix entries as PCI spec allows. To keep migration compatibility, 4096 is used for all callers and pba were start from half of bar size. Cc: Keith Busch keith.bu...@intel.com Cc: Kevin Wolf kw...@redhat.com Cc: Stefan Hajnoczi stefa...@redhat.com Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- hw/block/nvme.c| 2 +- hw/misc/ivshmem.c | 2 +- hw/pci/msix.c | 18 +++--- hw/virtio/virtio-pci.c | 2 +- include/hw/pci/msix.h | 2 +- 5 files changed, 11 insertions(+), 15 deletions(-) diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 0f3dfb9..09d7884 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -787,7 +787,7 @@ static int nvme_init(PCIDevice *pci_dev) pci_register_bar(n-parent_obj, 0, PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64, n-iomem); -msix_init_exclusive_bar(n-parent_obj, n-num_queues, 4); +msix_init_exclusive_bar(n-parent_obj, n-num_queues, 4, 4096); id-vid = cpu_to_le16(pci_get_word(pci_conf + PCI_VENDOR_ID)); id-ssvid = cpu_to_le16(pci_get_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID)); diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index 5d272c8..3e2a2d4 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -631,7 +631,7 @@ static uint64_t ivshmem_get_size(IVShmemState * s) { static void ivshmem_setup_msi(IVShmemState * s) { -if (msix_init_exclusive_bar(PCI_DEVICE(s), s-vectors, 1)) { +if (msix_init_exclusive_bar(PCI_DEVICE(s), s-vectors, 1, 4096)) { IVSHMEM_DPRINTF(msix initialization failed\n); exit(1); } diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 24de260..9a1894f 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -291,33 +291,29 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries, } int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, -uint8_t bar_nr) +uint8_t bar_nr, uint32_t bar_size) { int ret; char *name; +uint32_t bar_pba_offset = bar_size / 2; /* * Migration compatibility dictates that this remains a 4k * BAR with the vector table in the lower half and PBA in * the upper half. Do not use these elsewhere! */ -#define MSIX_EXCLUSIVE_BAR_SIZE 4096 -#define MSIX_EXCLUSIVE_BAR_TABLE_OFFSET 0 -#define MSIX_EXCLUSIVE_BAR_PBA_OFFSET (MSIX_EXCLUSIVE_BAR_SIZE / 2) -#define MSIX_EXCLUSIVE_CAP_OFFSET 0 - -if (nentries * PCI_MSIX_ENTRY_SIZE MSIX_EXCLUSIVE_BAR_PBA_OFFSET) { +if (nentries * PCI_MSIX_ENTRY_SIZE bar_pba_offset) { return -EINVAL; } name = g_strdup_printf(%s-msix, dev-name); -memory_region_init(dev-msix_exclusive_bar, OBJECT(dev), name, MSIX_EXCLUSIVE_BAR_SIZE); +memory_region_init(dev-msix_exclusive_bar, OBJECT(dev), name, bar_size); g_free(name); ret = msix_init(dev, nentries, dev-msix_exclusive_bar, bar_nr, -MSIX_EXCLUSIVE_BAR_TABLE_OFFSET, dev-msix_exclusive_bar, -bar_nr, MSIX_EXCLUSIVE_BAR_PBA_OFFSET, -MSIX_EXCLUSIVE_CAP_OFFSET); +0, dev-msix_exclusive_bar, +bar_nr, bar_pba_offset, +0); if (ret) { return ret; } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 02e3ce8..4a5febb 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -937,7 +937,7 @@ static void virtio_pci_device_plugged(DeviceState *d) config[PCI_INTERRUPT_PIN] = 1; if (proxy-nvectors -msix_init_exclusive_bar(proxy-pci_dev, proxy-nvectors, 1)) { +msix_init_exclusive_bar(proxy-pci_dev, proxy-nvectors, 1, 4096)) { error_report(unable to init msix vectors to % PRIu32, proxy-nvectors); proxy-nvectors = 0; diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h index 954d82b..43edebc 100644 --- a/include/hw/pci/msix.h +++ b/include/hw/pci/msix.h @@ -11,7 +11,7 @@ int msix_init(PCIDevice *dev, unsigned short nentries, unsigned table_offset, MemoryRegion *pba_bar, uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos); int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, -uint8_t bar_nr); +uint8_t bar_nr, uint32_t bar_size); void msix_write_config(PCIDevice *dev, uint32_t address, uint32_t val, int len); -- 2.1.0
[Qemu-devel] [PATCH V4 05/19] monitor: check return value of qemu_find_net_clients_except()
qemu_find_net_clients_except() may return a value which is greater than the size of array we provided. So we should check this value before using it, otherwise this may cause unexpected memory access. This patch fixes the net related command completion when we have a virtio-net nic with more than 255 queues. Cc: Luiz Capitulino lcapitul...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com --- monitor.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/monitor.c b/monitor.c index 07dfed0..3c0abfd 100644 --- a/monitor.c +++ b/monitor.c @@ -4480,7 +4480,7 @@ void set_link_completion(ReadLineState *rs, int nb_args, const char *str) count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NONE, MAX_QUEUE_NUM); -for (i = 0; i count; i++) { +for (i = 0; i MIN(count, MAX_QUEUE_NUM); i++) { const char *name = ncs[i]-name; if (!strncmp(str, name, len)) { readline_add_completion(rs, name); @@ -4505,7 +4505,7 @@ void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str) readline_set_completion_index(rs, len); count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NIC, MAX_QUEUE_NUM); -for (i = 0; i count; i++) { +for (i = 0; i MIN(count, MAX_QUEUE_NUM); i++) { QemuOpts *opts; const char *name = ncs[i]-name; if (strncmp(str, name, len)) { @@ -4579,7 +4579,7 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str) count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NONE, MAX_QUEUE_NUM); -for (i = 0; i count; i++) { +for (i = 0; i MIN(count, MAX_QUEUE_NUM); i++) { int id; char name[16]; @@ -4596,7 +4596,7 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str) count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NIC, MAX_QUEUE_NUM); -for (i = 0; i count; i++) { +for (i = 0; i MIN(count, MAX_QUEUE_NUM); i++) { int id; const char *name; -- 2.1.0
Re: [Qemu-devel] [RFC 0/5] Memory transaction attributes API
On 18 March 2015 at 08:38, Edgar E. Iglesias edgar.igles...@gmail.com wrote: 2. The series introduces the read and write _with_attrs. Another approach could be to add a (for example) single .access callback. The callback could take a structure pointer as input, e.g: struct MemTx { bool rw; hwaddr addr; int size; uint64_t data; MemTxAttrs attrs; } MemTxResult access(MemTx *tx) The benefit I see is that this will make it easier for us in the future to add new fields if needed. I see the reasoning, but I looked at this and it just felt awkward when I tried writing the code that way -- the code calling the access function ends up having to create and mutate this MemTx struct as it loops round calling the access callback. In particular, memory.c has kept the read and write paths separate all the way through, so squashing them back together into a single callback which will then immediately want to split them back out into read vs write seemed a bit daft. -- PMM
[Qemu-devel] [PULL 15/19] virtio-scsi: Fix assert in virtio_scsi_push_event
From: Fam Zheng f...@redhat.com Hotplugging a scsi-disk may trigger the assertion in qemu_sgl_concat. qemu-system-x86_64: qemu/hw/scsi/virtio-scsi.c:115: qemu_sgl_concat: Assertion `skip == 0' failed. This is introduced by commit 55783a55 (virtio-scsi: work around bug in old BIOSes) which didn't check out_num when accessing out_sg[0].iov_len (the same to in sg). For virtio_scsi_push_event, looking into out_sg doesn't make sense because 0 req_size is intended. Cc: qemu-sta...@nongnu.org [Cc'ing qemu-stable because 55783a55 did it too] Signed-off-by: Fam Zheng f...@redhat.com Message-Id: 1426233354-525-1-git-send-email-f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/scsi/virtio-scsi.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index da0cff8..c9bea06 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -146,8 +146,12 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req, * TODO: always disable this workaround for virtio 1.0 devices. */ if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) { -req_size = req-elem.out_sg[0].iov_len; -resp_size = req-elem.in_sg[0].iov_len; +if (req-elem.out_num) { +req_size = req-elem.out_sg[0].iov_len; +} +if (req-elem.in_num) { +resp_size = req-elem.in_sg[0].iov_len; +} } out_size = qemu_sgl_concat(req, req-elem.out_sg, -- 2.3.0
[Qemu-devel] [PULL 16/19] kvm: fix ioeventfd endianness on bi-endian architectures
From: Greg Kurz gk...@linux.vnet.ibm.com KVM expects host endian values. Hosts that don't use the default endianness need to negate the swap performed in adjust_endianness(). Suggested-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Greg Kurz gk...@linux.vnet.ibm.com Message-Id: 20150313212337.31142.3991.stgit@bahia.local Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- kvm-all.c | 24 ++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 55025cc..335438a 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -528,13 +528,33 @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension) return ret; } +static uint32_t adjust_ioeventfd_endianness(uint32_t val, uint32_t size) +{ +#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) +/* The kernel expects ioeventfd values in HOST_WORDS_BIGENDIAN + * endianness, but the memory core hands them in target endianness. + * For example, PPC is always treated as big-endian even if running + * on KVM and on PPC64LE. Correct here. + */ +switch (size) { +case 2: +val = bswap16(val); +break; +case 4: +val = bswap32(val); +break; +} +#endif +return val; +} + static int kvm_set_ioeventfd_mmio(int fd, hwaddr addr, uint32_t val, bool assign, uint32_t size, bool datamatch) { int ret; struct kvm_ioeventfd iofd; -iofd.datamatch = datamatch ? val : 0; +iofd.datamatch = datamatch ? adjust_ioeventfd_endianness(val, size) : 0; iofd.addr = addr; iofd.len = size; iofd.flags = 0; @@ -564,7 +584,7 @@ static int kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint16_t val, bool assign, uint32_t size, bool datamatch) { struct kvm_ioeventfd kick = { -.datamatch = datamatch ? val : 0, +.datamatch = datamatch ? adjust_ioeventfd_endianness(val, size) : 0, .addr = addr, .flags = KVM_IOEVENTFD_FLAG_PIO, .len = size, -- 2.3.0
Re: [Qemu-devel] [PATCH v2] hw/usb: Include USB files only if necessary
On Di, 2015-03-17 at 14:52 +0100, Thomas Huth wrote: Everything should now also compile fine again when configure has been run with the --enable-usb-redir and/or --enable-libusb option. Survived test now. Added to usb queue. thanks, Gerd
Re: [Qemu-devel] GSOC 2015 Project Proposal
On Mon, Feb 9, 2015 at 12:44 AM, Xin Tong trent.t...@gmail.com wrote: I would like to do GSOC this summer. The project i have in mind is to implement a set of facilities to make implementing Hardware transactional memory (HTM) easier in QEMU. HTM has become available in many architecture supported by QEMU, e.g. i386, PowerPC, etc. Currently, necessary memory tracking. conflict detection and transaction rollbak/commit are not available in QEMU. As a result, HTM is supported in a very rudimentary fashion in PowerPC, i.e. the transaction begins (tbegin in PowerPC) always trigger a fault to the fallback code path. Even though HTM is supported by different architectures, the underlying principle are very similar and therefore it is beneficial to provide a set of facilities to make implementing HTM easier in QEMU. These facilities should include. A modified software TLB to make memory address and value tracking simple. A performant and memory efficient value/address tracking facility to detect read/write conflicts for transactions. A performant and memory efficient mechanism to rollback and commit memory accesses. A mechanism to abort transactions on the current processor as well as remote processor. I will come up with a more detailed proposal as application time draws close. Any suggestions are appreciated at the moment. Hi Xin, Thanks for proposing this project idea. There haven't been any responses yet. I have CCed Alexander Graf and David Gibson, who have worked on the PowerPC target, and Richard Henderson in case he's interested in transactional memory. You need to find a mentor willing to supervise this project idea. Hopefully bumping this email thread will remind people to consider your idea. If no QEMU regular contributors are willing to mentor the project idea then I'm afraid you would have to choose another idea to apply for QEMU GSoC. Let me know if you have any questions or need help. Stefan
Re: [Qemu-devel] [PATCH v4 0/3] usb: fix segfault when hot-unplugging usb host adapter
On Mi, 2015-03-18 at 17:33 +0800, arei.gong...@huawei.com wrote: v4 - v3: - add reset hookup for sysbus devices (ehci/ohci). (Gerd) Replaced patches. make check failure is gone. Good. thanks, Gerd
[Qemu-devel] [PULL 3/8] pcie: correct mistaken register bit for End-End TLP Prefix Blocking
From: Chen Fan chen.fan.f...@cn.fujitsu.com from pcie spec 7.8.17, the End-End TLP Prefix Blocking bit local is 15(e.g. 0x8000) in device control 2 register. Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pcie_regs.h | 2 +- hw/pci/pcie.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h index 652d9fc..848ab1c 100644 --- a/include/hw/pci/pcie_regs.h +++ b/include/hw/pci/pcie_regs.h @@ -72,7 +72,7 @@ #define PCI_EXP_DEVCAP2_EFF 0x10 #define PCI_EXP_DEVCAP2_EETLPP 0x20 -#define PCI_EXP_DEVCTL2_EETLPPB 0x80 +#define PCI_EXP_DEVCTL2_EETLPPB 0x8000 /* ARI */ #define PCI_ARI_VER 1 diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 1a1..1463e65 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -84,7 +84,7 @@ int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port) pci_set_long(exp_cap + PCI_EXP_DEVCAP2, PCI_EXP_DEVCAP2_EFF | PCI_EXP_DEVCAP2_EETLPP); -pci_set_word(dev-wmask + pos, PCI_EXP_DEVCTL2_EETLPPB); +pci_set_word(dev-wmask + pos + PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_EETLPPB); return pos; } -- MST
[Qemu-devel] [PULL 7/8] pci: fix several trivial typos in comment
From: Chen Fan chen.fan.f...@cn.fujitsu.com Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pci.h | 2 +- include/hw/pci/pcie_aer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index be2d9b8..b97c295 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -137,7 +137,7 @@ enum { #define PCI_CONFIG_HEADER_SIZE 0x40 /* Size of the standard PCI config space */ #define PCI_CONFIG_SPACE_SIZE 0x100 -/* Size of the standart PCIe config space: 4KB */ +/* Size of the standard PCIe config space: 4KB */ #define PCIE_CONFIG_SPACE_SIZE 0x1000 #define PCI_NUM_PINS 4 /* A-D */ diff --git a/include/hw/pci/pcie_aer.h b/include/hw/pci/pcie_aer.h index bcac80a..2fb8388 100644 --- a/include/hw/pci/pcie_aer.h +++ b/include/hw/pci/pcie_aer.h @@ -51,7 +51,7 @@ struct PCIEAERLog { PCIEAERErr *log; }; -/* aer error message: error signaling message has only error sevirity and +/* aer error message: error signaling message has only error severity and source id. See 2.2.8.3 error signaling messages */ struct PCIEAERMsg { /* -- MST
Re: [Qemu-devel] [PATCH V4 19/19] virtio-pci: introduce auto_msix_bar_size property
On Wed, Mar 18, 2015 at 05:35:09PM +0800, Jason Wang wrote: Currently we don't support more than 128 MSI-X vectors for a pci devices, trying to use vector=129 for a virtio-net-pci device may get: qemu-system-x86_64: -device virtio-net-pci,netdev=hn0,vectors=129: unable to init msix vectors to 129 This this because the MSI-X bar size were hard-coded as 4096. So this patch introduces boolean auto_msix_bar_size property for virito-pci devices. Enable this will let the device calculate the msix bar size based on the number of MSI-X entries instead of previous 4096 hard-coded limit. This is a must to let virtio-net can up to 256 queues and each queue were associated with a specific MSI-X entry. Cc: Paolo Bonzini pbonz...@redhat.com Cc: Richard Henderson r...@twiddle.net Cc: Michael S. Tsirkin m...@redhat.com Cc: Alexander Graf ag...@suse.de Cc: qemu-...@nongnu.org Signed-off-by: Jason Wang jasow...@redhat.com I don't understand what this property does. What if I *don't* set auto_msix_bar_size? vectors=128 works exactly like it dif previously, vectors=129 fails? Does not seem like useful behaviour, to me. --- hw/i386/pc_piix.c | 8 hw/i386/pc_q35.c | 8 hw/ppc/spapr.c | 11 ++- hw/virtio/virtio-pci.c | 17 +++-- hw/virtio/virtio-pci.h | 3 +++ include/hw/compat.h| 11 +++ 6 files changed, 55 insertions(+), 3 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 0796719..8808500 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -552,6 +552,10 @@ static QEMUMachine pc_i440fx_machine_v2_3 = { PC_I440FX_2_3_MACHINE_OPTIONS, .name = pc-i440fx-2.3, .init = pc_init_pci_2_3, +.compat_props = (GlobalProperty[]) { +HW_COMPAT_2_3, +{ /* end of list */ } +}, }; #define PC_I440FX_2_2_MACHINE_OPTIONS PC_I440FX_2_3_MACHINE_OPTIONS @@ -560,6 +564,10 @@ static QEMUMachine pc_i440fx_machine_v2_2 = { PC_I440FX_2_2_MACHINE_OPTIONS, .name = pc-i440fx-2.2, .init = pc_init_pci_2_2, +.compat_props = (GlobalProperty[]) { +HW_COMPAT_2_2, +{ /* end of list */ } +}, }; #define PC_I440FX_2_1_MACHINE_OPTIONS \ diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index a8a34a4..4a34349 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -448,6 +448,10 @@ static QEMUMachine pc_q35_machine_v2_3 = { PC_Q35_2_3_MACHINE_OPTIONS, .name = pc-q35-2.3, .init = pc_q35_init_2_3, +.compat_props = (GlobalProperty[]) { +HW_COMPAT_2_3, +{ /* end of list */ } +}, }; #define PC_Q35_2_2_MACHINE_OPTIONS PC_Q35_2_3_MACHINE_OPTIONS @@ -456,6 +460,10 @@ static QEMUMachine pc_q35_machine_v2_2 = { PC_Q35_2_2_MACHINE_OPTIONS, .name = pc-q35-2.2, .init = pc_q35_init_2_2, +.compat_props = (GlobalProperty[]) { +HW_COMPAT_2_2, +{ /* end of list */ } +}, }; #define PC_Q35_2_1_MACHINE_OPTIONS \ diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5f25dd3..853a5cc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1794,12 +1794,16 @@ static const TypeInfo spapr_machine_info = { }, }; +#define SPAPR_COMPAT_2_3 \ +HW_COMPAT_2_3 + #define SPAPR_COMPAT_2_2 \ +SPAPR_COMPAT_2_3, \ {\ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\ .property = mem_win_size,\ .value= 0x2000,\ -} +} \ #define SPAPR_COMPAT_2_1 \ SPAPR_COMPAT_2_2 @@ -1883,10 +1887,15 @@ static const TypeInfo spapr_machine_2_2_info = { static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data) { +static GlobalProperty compat_props[] = { +SPAPR_COMPAT_2_3, +{ /* end of list */ } +}; MachineClass *mc = MACHINE_CLASS(oc); mc-name = pseries-2.3; mc-desc = pSeries Logical Partition (PAPR compliant) v2.3; +mc-compat_props = compat_props; } static const TypeInfo spapr_machine_2_3_info = { diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 4a5febb..f4cd405 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -925,7 +925,7 @@ static void virtio_pci_device_plugged(DeviceState *d) VirtIOPCIProxy *proxy = VIRTIO_PCI(d); VirtioBusState *bus = proxy-bus; uint8_t *config; -uint32_t size; +uint32_t size, bar_size; config = proxy-pci_dev.config; if (proxy-class_code) { @@ -936,8 +936,19 @@ static void virtio_pci_device_plugged(DeviceState *d) pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus)); config[PCI_INTERRUPT_PIN] = 1; +if (proxy-flags VIRTIO_PCI_FLAG_AUTO_MSIX_SIZE) { +bar_size = proxy-nvectors * PCI_MSIX_ENTRY_SIZE * 2; +if (bar_size (bar_size - 1)) { +bar_size = 1
Re: [Qemu-devel] [RFC PATCH 03/14] quorum: ignore 0-length child
On 2015-03-18 at 01:29, Wen Congyang wrote: On 02/24/2015 04:43 AM, Max Reitz wrote: On 2015-02-11 at 22:07, Wen Congyang wrote: We connect to NBD server when starting block replication, so the length is 0 before starting block replication. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com Signed-off-by: Gonglei arei.gong...@huawei.com --- block/quorum.c | 5 + 1 file changed, 5 insertions(+) diff --git a/block/quorum.c b/block/quorum.c index 5ed1ff8..e6aff5f 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -734,6 +734,11 @@ static int64_t quorum_getlength(BlockDriverState *bs) if (value 0) { return value; } + +if (!value) { +continue; +} + if (value != result) { return -EIO; } Hm, what do you think about some specific error value returned by your delayed NBD implementation? Like -ENOTCONN or something like that? Then we'd be able to discern a real 0-length block device from a not-yet-connected NBD server. In my newest test, it cannot return -ENOTCONN, otherwise bdrv_open() will fail when we open the child. Here is the backtrace: (gdb) bt #0 bdrv_open_common (bs=0x563b2230, file=0x0, options=0x563b55a0, flags=57410, drv=0x55e90c00, errp=0x7fffd460) at block.c:1070 #1 0x5595ea72 in bdrv_open (pbs=0x7fffd5f8, filename=0x0, reference=0x0, options=0x563b55a0, flags=57410, drv=0x55e90c00, errp=0x7fffd5e0) at block.c:1677 #2 0x5595e3a9 in bdrv_open_image (pbs=0x7fffd5f8, filename=0x0, options=0x563a6730, bdref_key=0x55a86b4c file, flags=57410, allow_none=true, errp=0x7fffd5e0) at block.c:1481 #3 0x5595e9ae in bdrv_open (pbs=0x56388008, filename=0x0, reference=0x0, options=0x563a6730, flags=8258, drv=0x55e8b800, errp=0x7fffd6b8) at block.c:1655 #4 0x559b0058 in quorum_open (bs=0x5639bd90, options=0x5639f100, flags=8258, errp=0x7fffd758) at block/quorum.c:1000 #5 0x5595d0b8 in bdrv_open_common (bs=0x5639bd90, file=0x0, options=0x5639f100, flags=8258, drv=0x55e8e5c0, errp=0x7fffd840) at block.c:1045 #6 0x5595ea72 in bdrv_open (pbs=0x5639bd50, filename=0x0, reference=0x0, options=0x5639f100, flags=8258, drv=0x55e8e5c0, errp=0x7fffdb70) at block.c:1677 #7 0x559b3bd3 in blk_new_open (name=0x5639bc60 virtio0, filename=0x0, reference=0x0, options=0x5639a420, flags=66, errp=0x7fffdb70) at block/block-backend.c:129 #8 0x55754f78 in blockdev_init (file=0x0, bs_opts=0x5639a420, errp=0x7fffdb70) at blockdev.c:536 #9 0x55755d90 in drive_new (all_opts=0x563777e0, block_default_type=IF_IDE) at blockdev.c:971 #10 0x5576b1f0 in drive_init_func (opts=0x563777e0, opaque=0x56372b48) at vl.c:1104 #11 0x55a1b019 in qemu_opts_foreach (list=0x55e44060, func=0x5576b1ba drive_init_func, opaque=0x56372b48, abort_on_failure=1) at util/qemu-option.c:1059 #12 0x557743dd in main (argc=25, argv=0x7fffe0c8, envp=0x7fffe198) at vl.c:4191 refresh_total_sectors() will fail if we return -ENOTCONN. Okay, then 0 will be fine, too. Max
Re: [Qemu-devel] [PATCH V4 08/19] virtio-net: fix the upper bound when trying to delete queues
On Wed, Mar 18, 2015 at 05:34:58PM +0800, Jason Wang wrote: Virtqueue were indexed from zero, so don't delete virtqueue whose index is n-max_queues * 2 + 1. Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com Bugfix? needed on master? stable? --- hw/net/virtio-net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 59f76bc..b6fac9c 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1309,7 +1309,7 @@ static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue) n-multiqueue = multiqueue; -for (i = 2; i = n-max_queues * 2 + 1; i++) { +for (i = 2; i n-max_queues * 2 + 1; i++) { virtio_del_queue(vdev, i); } -- 2.1.0
[Qemu-devel] [PULL 10/13] hw/usb: Include USB files only if necessary
From: Thomas Huth th...@linux.vnet.ibm.com Boards that do not include an USB controller should not provide USB devices. However, when running qemu-system-s390x -device help for example, there's still a usb-hub, usb-kbd, usb-mouse and usb-tablet in the list of supported devices. Let's fix that by compiling and linking the USB files only if it is really necessary. Signed-off-by: Thomas Huth th...@linux.vnet.ibm.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- default-configs/arm-softmmu.mak | 1 + default-configs/usb.mak | 1 + hw/usb/Makefile.objs| 8 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 87d4e34..a767e4b 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -32,6 +32,7 @@ CONFIG_DS1338=y CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI02=y CONFIG_MICRODRIVE=y +CONFIG_USB=y CONFIG_USB_MUSB=y CONFIG_USB_EHCI_SYSBUS=y CONFIG_PLATFORM_BUS=y diff --git a/default-configs/usb.mak b/default-configs/usb.mak index 73d8489..f4b8568 100644 --- a/default-configs/usb.mak +++ b/default-configs/usb.mak @@ -1,3 +1,4 @@ +CONFIG_USB=y CONFIG_USB_TABLET_WACOM=y CONFIG_USB_STORAGE_BOT=y CONFIG_USB_STORAGE_UAS=y diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs index 0ccd477..7443e38 100644 --- a/hw/usb/Makefile.objs +++ b/hw/usb/Makefile.objs @@ -1,6 +1,6 @@ # usb subsystem core -common-obj-y += core.o combined-packet.o bus.o desc.o desc-msos.o -common-obj-y += libhw.o +common-obj-y += core.o combined-packet.o bus.o libhw.o +common-obj-$(CONFIG_USB) += desc.o desc-msos.o # usb host adapters common-obj-$(CONFIG_USB_UHCI) += hcd-uhci.o @@ -11,8 +11,8 @@ common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o # emulated usb devices -common-obj-y += dev-hub.o -common-obj-y += dev-hid.o +common-obj-$(CONFIG_USB) += dev-hub.o +common-obj-$(CONFIG_USB) += dev-hid.o common-obj-$(CONFIG_USB_TABLET_WACOM) += dev-wacom.o common-obj-$(CONFIG_USB_STORAGE_BOT) += dev-storage.o common-obj-$(CONFIG_USB_STORAGE_UAS) += dev-uas.o -- 1.8.3.1
[Qemu-devel] [PULL 07/13] monitor usb: Inline monitor_read_bdrv_key_start()'s first part
From: Markus Armbruster arm...@redhat.com monitor_read_bdrv_key_start() does several things: 1. If no key is needed, call completion_cb() and succeed 2. If we're in QMP context, call qerror_report_err() and fail 3. Start reading the key in the monitor. This is two things too many. Inline 1. and 2. into its callers monitor_read_block_device_key() and usb_msd_realize_storage(). Since monitor_read_block_device_key() only ever runs in HMP context, drop 2. there. The next commit will clean up the result in usb_msd_realize_storage(). Signed-off-by: Markus Armbruster arm...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/usb/dev-storage.c | 13 +++-- monitor.c| 29 +++-- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index dacefd7..f47c856 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -641,8 +641,17 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp) if (bdrv_key_required(blk_bs(blk))) { if (cur_mon) { -monitor_read_bdrv_key_start(cur_mon, blk_bs(blk), -usb_msd_password_cb, s); +bdrv_add_key(blk_bs(blk), NULL, err); +if (!err) { +usb_msd_password_cb(s, 0); +} else if (monitor_cur_is_qmp()) { +qerror_report_err(err); +error_free(err); +} else { +error_free(err); +monitor_read_bdrv_key_start(cur_mon, blk_bs(blk), +usb_msd_password_cb, s); +} s-dev.auto_attach = 0; } else { autostart = 0; diff --git a/monitor.c b/monitor.c index bc77415..61c00ac 100644 --- a/monitor.c +++ b/monitor.c @@ -5377,25 +5377,8 @@ int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, BlockCompletionFunc *completion_cb, void *opaque) { -Error *local_err = NULL; int err; -bdrv_add_key(bs, NULL, local_err); -if (!local_err) { -if (completion_cb) -completion_cb(opaque, 0); -return 0; -} - -/* Need a key for @bs */ - -if (monitor_ctrl_mode(mon)) { -qerror_report_err(local_err); -error_free(local_err); -return -1; -} - -error_free(local_err); monitor_printf(mon, %s (%s) is encrypted.\n, bdrv_get_device_name(bs), bdrv_get_encrypted_filename(bs)); @@ -5414,6 +5397,7 @@ int monitor_read_block_device_key(Monitor *mon, const char *device, BlockCompletionFunc *completion_cb, void *opaque) { +Error *err = NULL; BlockBackend *blk; blk = blk_by_name(device); @@ -5422,7 +5406,16 @@ int monitor_read_block_device_key(Monitor *mon, const char *device, return -1; } -return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque); +bdrv_add_key(blk_bs(blk), NULL, err); +if (err) { +error_free(err); +return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque); +} + +if (completion_cb) { +completion_cb(opaque, 0); +} +return 0; } QemuOptsList qemu_mon_opts = { -- 1.8.3.1
[Qemu-devel] [PULL 03/13] ohci: Complete conversion to realize
From: Markus Armbruster arm...@redhat.com Commit 457215ec ohci: Use QOM realize for OHCI converted only sysbus-ohci. Finish the job: convert pci-ohci. Signed-off-by: Markus Armbruster arm...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/usb/hcd-ohci.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 21ec65f..e180a17 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -1827,10 +1827,10 @@ static USBPortOps ohci_port_ops = { static USBBusOps ohci_bus_ops = { }; -static int usb_ohci_init(OHCIState *ohci, DeviceState *dev, - int num_ports, dma_addr_t localmem_base, - char *masterbus, uint32_t firstport, - AddressSpace *as) +static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, + int num_ports, dma_addr_t localmem_base, + char *masterbus, uint32_t firstport, + AddressSpace *as, Error **errp) { Error *err = NULL; int i; @@ -1863,8 +1863,8 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev, USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL, err); if (err) { -error_report_err(err); -return -1; +error_propagate(errp, err); +return; } } else { usb_bus_new(ohci-bus, sizeof(ohci-bus), ohci_bus_ops, dev); @@ -1884,8 +1884,6 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev, ohci-async_td = 0; qemu_register_reset(ohci_reset, ohci); - -return 0; } #define TYPE_PCI_OHCI pci-ohci @@ -1918,22 +1916,24 @@ static void ohci_die(OHCIState *ohci) PCI_STATUS_DETECTED_PARITY); } -static int usb_ohci_initfn_pci(PCIDevice *dev) +static void usb_ohci_realize_pci(PCIDevice *dev, Error **errp) { +Error *err = NULL; OHCIPCIState *ohci = PCI_OHCI(dev); dev-config[PCI_CLASS_PROG] = 0x10; /* OHCI */ dev-config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */ -if (usb_ohci_init(ohci-state, DEVICE(dev), ohci-num_ports, 0, - ohci-masterbus, ohci-firstport, - pci_get_address_space(dev)) != 0) { -return -1; +usb_ohci_init(ohci-state, DEVICE(dev), ohci-num_ports, 0, + ohci-masterbus, ohci-firstport, + pci_get_address_space(dev), err); +if (err) { +error_propagate(errp, err); +return; } -ohci-state.irq = pci_allocate_irq(dev); +ohci-state.irq = pci_allocate_irq(dev); pci_register_bar(dev, 0, 0, ohci-state.mem); -return 0; } static void usb_ohci_exit(PCIDevice *dev) @@ -1975,7 +1975,7 @@ static void ohci_realize_pxa(DeviceState *dev, Error **errp) /* Cannot fail as we pass NULL for masterbus */ usb_ohci_init(s-ohci, dev, s-num_ports, s-dma_offset, NULL, 0, - address_space_memory); + address_space_memory, error_abort); sysbus_init_irq(sbd, s-ohci.irq); sysbus_init_mmio(sbd, s-ohci.mem); } @@ -2091,7 +2091,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); -k-init = usb_ohci_initfn_pci; +k-realize = usb_ohci_realize_pci; k-exit = usb_ohci_exit; k-vendor_id = PCI_VENDOR_ID_APPLE; k-device_id = PCI_DEVICE_ID_APPLE_IPID_USB; -- 1.8.3.1
[Qemu-devel] [PULL 09/13] usb/dev-storage: Avoid qerror_report_err() outside QMP handlers
From: Markus Armbruster arm...@redhat.com qerror_report_err() is a transitional interface to help with converting existing monitor commands to QMP. It should not be used elsewhere. usb_msd_password_cb() is only called from within an HMP command handler. Replace by error_report_err(). Signed-off-by: Markus Armbruster arm...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/usb/dev-storage.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index f50bcb8..ae8d40d 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -559,8 +559,7 @@ static void usb_msd_password_cb(void *opaque, int err) } if (local_err) { -qerror_report_err(local_err); -error_free(local_err); +error_report_err(local_err); qdev_unplug(s-dev.qdev, NULL); } } -- 1.8.3.1
[Qemu-devel] [PULL 5/9] ui: split setup of VNC auth scheme into separate method
From: Daniel P. Berrange berra...@redhat.com The vnc_display_open method is quite long and complex, so move the VNC auth scheme decision logic into a separate method for clarity. Also update the comment to better describe what we are trying to achieve. Signed-off-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/vnc.c | 153 +-- 1 file changed, 91 insertions(+), 62 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index d5e6024..8edbb67 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3314,6 +3314,96 @@ static QemuOptsList qemu_vnc_opts = { }, }; + +static void +vnc_display_setup_auth(VncDisplay *vs, + bool password, + bool sasl, + bool tls, + bool x509) +{ +/* + * We have a choice of 3 authentication options + * + * 1. none + * 2. vnc + * 3. sasl + * + * The channel can be run in 2 modes + * + * 1. clear + * 2. tls + * + * And TLS can use 2 types of credentials + * + * 1. anon + * 2. x509 + * + * We thus have 9 possible logical combinations + * + * 1. clear + none + * 2. clear + vnc + * 3. clear + sasl + * 4. tls + anon + none + * 5. tls + anon + vnc + * 6. tls + anon + sasl + * 7. tls + x509 + none + * 8. tls + x509 + vnc + * 9. tls + x509 + sasl + * + * These need to be mapped into the VNC auth schemes + * in an appropriate manner. In regular VNC, all the + * TLS options get mapped into VNC_AUTH_VENCRYPT + * sub-auth types. + */ +if (password) { +if (tls) { +vs-auth = VNC_AUTH_VENCRYPT; +if (x509) { +VNC_DEBUG(Initializing VNC server with x509 password auth\n); +vs-subauth = VNC_AUTH_VENCRYPT_X509VNC; +} else { +VNC_DEBUG(Initializing VNC server with TLS password auth\n); +vs-subauth = VNC_AUTH_VENCRYPT_TLSVNC; +} +} else { +VNC_DEBUG(Initializing VNC server with password auth\n); +vs-auth = VNC_AUTH_VNC; +vs-subauth = VNC_AUTH_INVALID; +} +} else if (sasl) { +if (tls) { +vs-auth = VNC_AUTH_VENCRYPT; +if (x509) { +VNC_DEBUG(Initializing VNC server with x509 SASL auth\n); +vs-subauth = VNC_AUTH_VENCRYPT_X509SASL; +} else { +VNC_DEBUG(Initializing VNC server with TLS SASL auth\n); +vs-subauth = VNC_AUTH_VENCRYPT_TLSSASL; +} +} else { +VNC_DEBUG(Initializing VNC server with SASL auth\n); +vs-auth = VNC_AUTH_SASL; +vs-subauth = VNC_AUTH_INVALID; +} +} else { +if (tls) { +vs-auth = VNC_AUTH_VENCRYPT; +if (x509) { +VNC_DEBUG(Initializing VNC server with x509 no auth\n); +vs-subauth = VNC_AUTH_VENCRYPT_X509NONE; +} else { +VNC_DEBUG(Initializing VNC server with TLS no auth\n); +vs-subauth = VNC_AUTH_VENCRYPT_TLSNONE; +} +} else { +VNC_DEBUG(Initializing VNC server with no auth\n); +vs-auth = VNC_AUTH_NONE; +vs-subauth = VNC_AUTH_INVALID; +} +} +} + void vnc_display_open(const char *id, Error **errp) { VncDisplay *vs = vnc_display_find(id); @@ -3506,68 +3596,7 @@ void vnc_display_open(const char *id, Error **errp) } #endif -/* - * Combinations we support here: - * - * - no-auth(clear text, no auth) - * - password (clear text, weak auth) - * - sasl (encrypt, good auth *IF* using Kerberos via GSSAPI) - * - tls(encrypt, weak anonymous creds, no auth) - * - tls + password (encrypt, weak anonymous creds, weak auth) - * - tls + sasl (encrypt, weak anonymous creds, good auth) - * - tls + x509 (encrypt, good x509 creds, no auth) - * - tls + x509 + password (encrypt, good x509 creds, weak auth) - * - tls + x509 + sasl (encrypt, good x509 creds, good auth) - * - * NB1. TLS is a stackable auth scheme. - * NB2. the x509 schemes have option to validate a client cert dname - */ -if (password) { -if (tls) { -vs-auth = VNC_AUTH_VENCRYPT; -if (x509) { -VNC_DEBUG(Initializing VNC server with x509 password auth\n); -vs-subauth = VNC_AUTH_VENCRYPT_X509VNC; -} else { -VNC_DEBUG(Initializing VNC server with TLS password auth\n); -vs-subauth = VNC_AUTH_VENCRYPT_TLSVNC; -} -} else { -VNC_DEBUG(Initializing VNC server with
[Qemu-devel] [PATCH 1/8] memory: Add global-locking property to memory regions
From: Jan Kiszka jan.kis...@siemens.com This introduces the memory region property global_locking. It is true by default. By setting it to false, a device model can request BQL-free dispatching of region accesses to its r/w handlers. The actual BQL break-up will be provided in a separate patch. Signed-off-by: Jan Kiszka jan.kis...@siemens.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- include/exec/memory.h | 26 ++ memory.c | 11 +++ 2 files changed, 37 insertions(+) diff --git a/include/exec/memory.h b/include/exec/memory.h index 06ffa1d..0ee2079 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -158,6 +158,7 @@ struct MemoryRegion { bool rom_device; bool warning_printed; /* For reservations */ bool flush_coalesced_mmio; +bool global_locking; MemoryRegion *alias; hwaddr alias_offset; int32_t priority; @@ -778,6 +779,31 @@ void memory_region_set_flush_coalesced(MemoryRegion *mr); void memory_region_clear_flush_coalesced(MemoryRegion *mr); /** + * memory_region_set_global_locking: Declares the access processing requires + * QEMU's global lock. + * + * When this is invoked, access to this memory regions will be processed while + * holding the global lock of QEMU. This is the default behavior of memory + * regions. + * + * @mr: the memory region to be updated. + */ +void memory_region_set_global_locking(MemoryRegion *mr); + +/** + * memory_region_clear_global_locking: Declares that access processing does + * not depend on the QEMU global lock. + * + * By clearing this property, accesses to the memory region will be processed + * outside of QEMU's global lock (unless the lock is held on when issuing the + * access request). In this case, the device model implementing the access + * handlers is responsible for synchronization of concurrency. + * + * @mr: the memory region to be updated. + */ +void memory_region_clear_global_locking(MemoryRegion *mr); + +/** * memory_region_add_eventfd: Request an eventfd to be triggered when a word *is written to a location. * diff --git a/memory.c b/memory.c index ee3f2a8..cc798e1 100644 --- a/memory.c +++ b/memory.c @@ -953,6 +953,7 @@ static void memory_region_initfn(Object *obj) mr-ops = unassigned_mem_ops; mr-enabled = true; mr-romd_mode = true; +mr-global_locking = true; mr-destructor = memory_region_destructor_none; QTAILQ_INIT(mr-subregions); QTAILQ_INIT(mr-coalesced); @@ -1549,6 +1550,16 @@ void memory_region_clear_flush_coalesced(MemoryRegion *mr) } } +void memory_region_set_global_locking(MemoryRegion *mr) +{ +mr-global_locking = true; +} + +void memory_region_clear_global_locking(MemoryRegion *mr) +{ +mr-global_locking = false; +} + void memory_region_add_eventfd(MemoryRegion *mr, hwaddr addr, unsigned size, -- 2.3.0
Re: [Qemu-devel] [PATCH v5 7/7] pc: add PC_I440FX_COMPAT to disable aercap for vifo device
typo in subject: vfio, not vifo. On Thu, Mar 12, 2015 at 06:23:59PM +0800, Chen Fan wrote: for piix4 chipset, we don't need to expose aer, so introduce PC_I440FX_COMPAT for all piix4 machines to disable aercap, and add HW_COMPAT_2_2 to disable aercap for all lower than 2.3. Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com Well vfio is never migrated ATM. So why is compat code needed at all? --- hw/i386/pc_piix.c | 9 + hw/i386/pc_q35.c| 4 include/hw/compat.h | 10 ++ 3 files changed, 23 insertions(+) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 8eab4ba..ff9d312 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -307,6 +307,11 @@ static void pc_init1(MachineState *machine, static void pc_init_pci(MachineState *machine) { +static GlobalProperty pc_compat_props[] = { +PC_I440FX_COMPAT, +{ /* end of list */ } +}; +qdev_prop_register_global_list(pc_compat_props); pc_init1(machine, 1, 1); } @@ -534,6 +539,10 @@ static QEMUMachine pc_i440fx_machine_v2_2 = { PC_I440FX_2_2_MACHINE_OPTIONS, .name = pc-i440fx-2.2, .init = pc_init_pci_2_2, +.compat_props = (GlobalProperty[]) { +HW_COMPAT_2_2, +{ /* end of list */ } +}, }; #define PC_I440FX_2_1_MACHINE_OPTIONS \ diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index c0f21fe..97afb7d 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -431,6 +431,10 @@ static QEMUMachine pc_q35_machine_v2_2 = { PC_Q35_2_2_MACHINE_OPTIONS, .name = pc-q35-2.2, .init = pc_q35_init_2_2, +.compat_props = (GlobalProperty[]) { +HW_COMPAT_2_2, +{ /* end of list */ } +}, }; #define PC_Q35_2_1_MACHINE_OPTIONS \ diff --git a/include/hw/compat.h b/include/hw/compat.h index 313682a..40c974a 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -1,7 +1,17 @@ #ifndef HW_COMPAT_H #define HW_COMPAT_H +#define HW_COMPAT_2_2 PC_I440FX_COMPAT + +#define PC_I440FX_COMPAT \ +{\ +.driver = vfio-pci,\ +.property = x-aer,\ +.value= off,\ +} + #define HW_COMPAT_2_1 \ +HW_COMPAT_2_2, \ {\ .driver = intel-hda,\ .property = old_msi_addr,\ -- 1.9.3
Re: [Qemu-devel] [PATCH 09/11] iotests: test 124 - drive object refactoring
On 2015-03-17 at 19:40, John Snow wrote: On 03/17/2015 04:44 PM, Max Reitz wrote: On 2015-03-04 at 23:15, John Snow wrote: The original test was not particularly good about keeping the relationships between bitmaps, drives, and images very explicit, so this patch adds an explicit 'drive' dict that is used to keep these relationships explicit. This is necessary in order to test two full backup chains simultaneously for two drives, which will happen in a forthcoming test that examines failure scenarios for incremental backups created for multiple drives in a single transaction. Highlights: - Each test case carries around a list of drives - Each bitmap now acknowledges the full backup belonging to the drive as its last target if it hasn't made an incremental backup yet. - Most functions generally try to accept a drive argument instead of target or format arguments. - Filenames are now based on their formatting and id name. Signed-off-by: John Snow js...@redhat.com --- tests/qemu-iotests/124 | 212 + 1 file changed, 126 insertions(+), 86 deletions(-) How about putting the previous patch in your transactionless series and squashing this one into the respective patches there? I don't want to startle the cat. I'd rather get the 'transactionless' checked in, then worry about features that are important for transactions in the series that introduces those features. If we keep thinking Oh, but this function hasn't gone upstream in the first place, so let's fix it there in this series, then the first series getting committed is going to wind up dependent on this series getting reviewed as we keep changing things. Since this group of patches is more experimental, I'd really prefer to keep it separate that way. Even if this patch is ugly. Sorry about that. Well, you're targetting 2.4 with your other series anyway. I understand that it's been a couple of revisions already and you really want to get it merged by now, but this is a test, so if you just squash it in there, I don't think it will hold up that series much. (A good rule for tests is: As long as they're passing and catch all desirable cases, nobody will really complain) Up to you, but I guess you can see how this patch just looks like I should have done it differently in the first place, and because that first place is still in flight, I'm wondering why you're not just fixing it there. Max Reviewed-by: Max Reitz mre...@redhat.com Some remarks below, whether you follow them or not is up to you. diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124 index da0bf6d..2eccc3e 100644 --- a/tests/qemu-iotests/124 +++ b/tests/qemu-iotests/124 @@ -29,14 +29,18 @@ def io_write_patterns(img, patterns): iotests.qemu_io('-c', 'write -P%s %s %s' % pattern, img) class Bitmap: -def __init__(self, name, node): +def __init__(self, name, drive): self.name = name -self.node = node +self.drive = drive self.pattern = os.path.join(iotests.test_dir.replace('%', '%%'), -'%s.backup.%%i.img' % name) +'%s.%s.backup.%%i.img' % (drive['id'], + name)) self.num = 0 self.backups = list() +def base_target(self): +return self.drive['backup'] + def new_target(self, num=None): if num is None: num = self.num @@ -46,7 +50,9 @@ class Bitmap: return target def last_target(self): -return self.backups[-1] +if self.backups: +return self.backups[-1] +return self.base_target() def del_target(self): os.remove(self.backups.pop()) @@ -63,19 +69,35 @@ class TestIncrementalBackup(iotests.QMPTestCase): def setUp(self): self.bitmaps = list() self.files = list() +self.drives = list() self.vm = iotests.VM() -self.test_img = os.path.join(iotests.test_dir, 'base.img') -self.full_bak = os.path.join(iotests.test_dir, 'backup.img') -self.foo_img = os.path.join(iotests.test_dir, 'foo.bar') -self.img_create(self.test_img, iotests.imgfmt) -self.vm.add_drive(self.test_img) +self.err_img = os.path.join(iotests.test_dir, 'err.%s' % iotests.imgfmt) Nice. *g* (using the format name as the file extension) ((even though you're not doing it in __init__)) Can't please everyone. :) + # Create a base image with a distinctive patterning -io_write_patterns(self.test_img, (('0x41', 0, 512), - ('0xd5', '1M', '32k'), - ('0xdc', '32M', '124k'))) +drive0 = self.add_node('drive0') +self.img_create(drive0['file'], drive0['fmt']) +self.vm.add_drive(drive0['file']) +io_write_patterns(drive0['file'], (('0x41', 0, 512), +
[Qemu-devel] [PULL 19/19] exec: Respect as_tranlsate_internal length clamp
From: Peter Crosthwaite peter.crosthwa...@xilinx.com address_space_translate_internal will clamp the *plen length argument based on the size of the memory region being queried. The iommu walker logic in addresss_space_translate was ignoring this by discarding the post fn call value of *plen. Fix by just always using *plen as the length argument throughout the fn, removing the len local variable. This fixes a bootloader bug when a single elf section spans multiple QEMU memory regions. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Message-Id: 1426570554-15940-1-git-send-email-peter.crosthwa...@xilinx.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- exec.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/exec.c b/exec.c index e97071a..8b922db 100644 --- a/exec.c +++ b/exec.c @@ -380,7 +380,6 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, IOMMUTLBEntry iotlb; MemoryRegionSection *section; MemoryRegion *mr; -hwaddr len = *plen; rcu_read_lock(); for (;;) { @@ -395,7 +394,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, iotlb = mr-iommu_ops-translate(mr, addr, is_write); addr = ((iotlb.translated_addr ~iotlb.addr_mask) | (addr iotlb.addr_mask)); -len = MIN(len, (addr | iotlb.addr_mask) - addr + 1); +*plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1); if (!(iotlb.perm (1 is_write))) { mr = io_mem_unassigned; break; @@ -406,10 +405,9 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, if (xen_enabled() memory_access_is_direct(mr, is_write)) { hwaddr page = ((addr TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr; -len = MIN(page, len); +*plen = MIN(page, *plen); } -*plen = len; *xlat = addr; rcu_read_unlock(); return mr; -- 2.3.0
[Qemu-devel] [PULL 11/19] nbd: Fix interpretation of the export flags
From: Max Reitz mre...@redhat.com The export flags are a 16 bit value, so be16_to_cpu() has to be used to interpret them correctly. This makes discard and flush actually work for named NBD exports (they did not work before, because the client always assumed them to be unsupported because of the bug fixed by this patch). Signed-off-by: Max Reitz mre...@redhat.com Message-Id: 1424887718-10800-20-git-send-email-mre...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- nbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nbd.c b/nbd.c index fb8a4d4..563e820 100644 --- a/nbd.c +++ b/nbd.c @@ -625,7 +625,7 @@ int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags, error_setg(errp, Failed to read export flags); goto fail; } -*flags |= be32_to_cpu(tmp); +*flags |= be16_to_cpu(tmp); } if (read_sync(csock, buf, 124) != 124) { error_setg(errp, Failed to read reserved block); -- 2.3.0
[Qemu-devel] [PATCH] virtio: move sanity checks to ifdef DEBUG
All that happens when virtqueue_fill is invoked incorrectly is that we corrupt guest memory, so this check is not a security measure. Move the check to ifdef DEBUG to make sure we don't introduce new crashes close to release. Array scans aren't free either, so it's a good idea from performance point of view, too. Cc: Rusty Russell ru...@rustcorp.com.au Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/virtio/virtio.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 27429c2..37fb2ee 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -243,15 +243,22 @@ int virtio_queue_empty(VirtQueue *vq) void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len_written, unsigned int idx) { -unsigned int offset, tot_wlen; +unsigned int offset; int i; trace_virtqueue_fill(vq, elem, len_written, idx); -for (tot_wlen = i = 0; i elem-in_num; i++) { -tot_wlen += elem-in_sg[i].iov_len; +#ifdef DEBUG_VIRTIO +{ +/* Check that len_written is = the writable length. */ +unsigned int tot_wlen; + +for (tot_wlen = i = 0; i elem-in_num; i++) { +tot_wlen += elem-in_sg[i].iov_len; +} +assert(len_written = tot_wlen); } -assert(len_written = tot_wlen); +#endif offset = 0; for (i = 0; i elem-in_num; i++) { -- MST
Re: [Qemu-devel] [PATCH 05/11] block: add delayed bitmap successor cleanup
On 2015-03-17 at 18:46, John Snow wrote: On 03/17/2015 02:44 PM, Max Reitz wrote: On 2015-03-04 at 23:15, John Snow wrote: [snip] +} +} + +BdrvDirtyBitmap *bdrv_dirty_bitmap_decref(BlockDriverState *bs, I don't know whether I'm that content with the name chosen, because you're actually decrementing the refcount of the successor; but since the successor is basically a clone of the original bitmap (and I mean in the Star Trek sense, that it's a teleported clone and the original is intended to be destroyed so the successor can replace it), decrementing the refcount of the successor basically is equal to decrementing the refcount of the bitmap itself (as long as there is a successor, which you are asserting; maybe you want to add a comment about that to include/block/block.h, that one can only use this on frozen bitmaps?). I could get clever with the name and call it bdrv_frozen_bitmap_decref, which hopefully still shows membership to the bdrv_dirty_bitmap class of functions but clarifies its usage sufficiently. Sounds good to me. [snip] diff --git a/block/backup.c b/block/backup.c index 41bd9af..4332df4 100644 --- a/block/backup.c +++ b/block/backup.c @@ -240,6 +240,12 @@ static void backup_complete(BlockJob *job, void *opaque) bdrv_unref(s-target); +if (s-sync_bitmap) { +BdrvDirtyBitmap *bm; +bm = bdrv_dirty_bitmap_decref(job-bs, s-sync_bitmap, data-ret, NULL); +assert(bm); You can use error_abort as the Error object and drop the assert(); or, if you are dropping the Error parameter, there is no need to check the return value at all, because it will always be non-NULL (there won't be any code path in the function returning NULL at all). Maybe you can even drop the return value, too. I just looked through the series: Actually, you're never using the Error parameter for bdrv_dirty_bitmap_decref() at all. Seems to me like you really should drop it (and maybe the return value along with it). I actually use this parameter to return the new bitmap (if any) after the decrement operation. I wanted to leave the window open for merge optimizations, so I tell the caller which bitmap remains after the operation. I will cull the errp, but will likely leave the return code. OK. Max
Re: [Qemu-devel] [PATCH target-arm v3 04/15] arm: xlnx-zynqmp: Add GIC
On Wed, Mar 18, 2015 at 10:26 AM, Alistair Francis alistair.fran...@xilinx.com wrote: On Mon, Mar 16, 2015 at 10:12 PM, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: And connect IRQ outputs to the CPUs. Reviewed-by: Alistair Francis alistair.fran...@xilinx.com Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- hw/arm/xlnx-zynqmp.c | 19 +++ include/hw/arm/xlnx-zynqmp.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 41c207a..9465185 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -17,6 +17,11 @@ #include hw/arm/xlnx-zynqmp.h +#define GIC_NUM_SPI_INTR 128 + +#define GIC_DIST_ADDR 0xf901 +#define GIC_CPU_ADDR0xf902 + static void xlnx_zynqmp_init(Object *obj) { XlnxZynqMPState *s = XLNX_ZYNQMP(obj); @@ -28,6 +33,9 @@ static void xlnx_zynqmp_init(Object *obj) object_property_add_child(obj, cpu[*], OBJECT(s-cpu[i]), error_abort); } + +object_initialize(s-gic, sizeof(s-gic), TYPE_ARM_GIC); +qdev_set_parent_bus(DEVICE(s-gic), sysbus_get_default()); } #define ERR_PROP_CHECK_RETURN(err, errp) do { \ @@ -43,9 +51,20 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) uint8_t i; Error *err = NULL; +qdev_prop_set_uint32(DEVICE(s-gic), num-irq, GIC_NUM_SPI_INTR + 32); +qdev_prop_set_uint32(DEVICE(s-gic), revision, 2); +qdev_prop_set_uint32(DEVICE(s-gic), num-cpu, XLNX_ZYNQMP_NUM_CPUS); +object_property_set_bool(OBJECT(s-gic), true, realized, err); +ERR_PROP_CHECK_RETURN(err, errp); +sysbus_mmio_map(SYS_BUS_DEVICE(s-gic), 0, GIC_DIST_ADDR); +sysbus_mmio_map(SYS_BUS_DEVICE(s-gic), 1, GIC_CPU_ADDR); + Hey Peter, The GIC here is causing seg faults because it is being connected before the CPUs. So I actually bisected this as a recent regression on: commit a464982499b2f637f6699e3d03e0a9d2e0b5288b (refs/bisect/bad) Author: Paolo Bonzini pbonz...@redhat.com Date: Wed Feb 11 17:15:18 2015 +0100 rcu: run RCU callbacks under the BQL This needs to go away sooner or later, but one complication is the complex VFIO data structures that are modified in instance_finalize. Take a shortcut for now. Reviewed-by: Michael Roth mdr...@linux.vnet.ibm.com Tested-by: Michael Roth mdr...@linux.vnet.ibm.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com Segfault backtrace: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7fffecd57700 (LWP 20522)] 0x55621580 in qemu_cpu_kick_thread (cpu=0x77f24088) at /workspaces/pcrost/ssiv/qemu-mainline/cpus.c:1052 1052err = pthread_kill(cpu-thread-thread, SIG_IPI); (gdb) bt #0 0x55621580 in qemu_cpu_kick_thread (cpu=0x77f24088) at /workspaces/pcrost/ssiv/qemu-mainline/cpus.c:1052 #1 0x55622a48 in qemu_mutex_lock_iothread () at /workspaces/pcrost/ssiv/qemu-mainline/cpus.c:1127 #2 0x558d6423 in call_rcu_thread (opaque=optimized out) at util/rcu.c:241 #3 0x740600a5 in start_thread (arg=0x7fffecd57700) at pthread_create.c:309 #4 0x73d8dcfd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 (gdb) I have sent an RFC for a patch that should fix it. This is easily fixed by moving the CPU creation first and then connect the GIC/CPU This will work too, but I think having requirements on ordering of dev inits is fragile and we should avoid it where possible. I'll do your proposed re-ordering if the fix doesn't get through. Regards, Peter lines after that. It shouldn't break anything as the GIC/CPU connections happen after realize anyway. See the code below for what works for me (can boot u-boot): for (i = 0; i XLNX_ZYNQMP_NUM_CPUS; i++) { object_property_set_int(OBJECT(s-cpu[i]), QEMU_PSCI_CONDUIT_SMC, psci-conduit, error_abort); if (i 0) { /* Secondary CPUs start in PSCI powered-down state */ object_property_set_bool(OBJECT(s-cpu[i]), true, start-powered-off, error_abort); } object_property_set_bool(OBJECT(s-cpu[i]), true, realized, err); ERR_PROP_CHECK_RETURN(err, errp); } qdev_prop_set_uint32(DEVICE(s-gic), num-irq, GIC_NUM_SPI_INTR + 32); qdev_prop_set_uint32(DEVICE(s-gic), revision, 2); qdev_prop_set_uint32(DEVICE(s-gic), num-cpu, XLNX_ZYNQMP_NUM_CPUS); object_property_set_bool(OBJECT(s-gic), true, realized, err); ERR_PROP_CHECK_RETURN(err, errp); sysbus_mmio_map(SYS_BUS_DEVICE(s-gic), 0, GIC_DIST_ADDR); sysbus_mmio_map(SYS_BUS_DEVICE(s-gic), 1, GIC_CPU_ADDR); for (i = 0; i XLNX_ZYNQMP_NUM_CPUS; i++) { sysbus_connect_irq(SYS_BUS_DEVICE(s-gic), i, qdev_get_gpio_in(DEVICE(s-cpu[i]), ARM_CPU_IRQ)); irq =
[Qemu-devel] [PULL 2/9] ui: remove unused 'wiremode' variable in VncState struct
From: Daniel P. Berrange berra...@redhat.com Signed-off-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/vnc-auth-vencrypt.c | 1 - ui/vnc-tls.c | 2 -- ui/vnc-tls.h | 7 --- ui/vnc-ws.c| 1 - 4 files changed, 11 deletions(-) diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c index bc7032e..a420ccb 100644 --- a/ui/vnc-auth-vencrypt.c +++ b/ui/vnc-auth-vencrypt.c @@ -93,7 +93,6 @@ static int vnc_start_vencrypt_handshake(struct VncState *vs) { } VNC_DEBUG(Handshake done, switching to TLS data mode\n); -vs-tls.wiremode = VNC_WIREMODE_TLS; qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, vnc_client_write, vs); start_auth_vencrypt_subauth(vs); diff --git a/ui/vnc-tls.c b/ui/vnc-tls.c index 0f59f9b..de1cb34 100644 --- a/ui/vnc-tls.c +++ b/ui/vnc-tls.c @@ -421,14 +421,12 @@ void vnc_tls_client_cleanup(struct VncState *vs) gnutls_deinit(vs-tls.session); vs-tls.session = NULL; } -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-tls.h b/ui/vnc-tls.h index 36a2227..f9829c7 100644 --- a/ui/vnc-tls.h +++ b/ui/vnc-tls.h @@ -33,11 +33,6 @@ #include qemu/acl.h -enum { -VNC_WIREMODE_CLEAR, -VNC_WIREMODE_TLS, -}; - typedef struct VncDisplayTLS VncDisplayTLS; typedef struct VncStateTLS VncStateTLS; @@ -55,8 +50,6 @@ struct VncDisplayTLS { /* Per client state */ struct VncStateTLS { -/* Whether data is being TLS encrypted yet */ -int wiremode; gnutls_session_t session; /* Client's Distinguished Name from the x509 cert */ diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c index d75950d..1769d52 100644 --- a/ui/vnc-ws.c +++ b/ui/vnc-ws.c @@ -48,7 +48,6 @@ static int vncws_start_tls_handshake(struct VncState *vs) } 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; -- 1.8.3.1
[Qemu-devel] [PULL for-2.3 0/9] vnc patch queue.
Hi, One QMP fix from Markus, needs to go into 2.3 because it is a API fix. A bunch of websocket fixes from Daniel, with some cleanup work. The problems fixed are serious enouth that I don't want delay this to 2.4 even though there are some non-trivial changes in the vnc websockets code. please pull, Gerd The following changes since commit 5a4992834daec85c3913654903fb9f4f954e585a: Merge remote-tracking branch 'remotes/armbru/tags/pull-cov-model-2015-03-17' into staging (2015-03-17 11:43:00 +) are available in the git repository at: git://git.kraxel.org/qemu tags/pull-vnc-20150318-1 for you to fetch changes up to 4a48aaa9f52dbac148be24f591de2f28c58ccb5d: ui: ensure VNC websockets server checks the ACL if requested (2015-03-18 09:25:14 +0100) vnc: fix websockets QMP. Daniel P. Berrange (8): ui: remove unused 'wiremode' variable in VncState struct ui: replace printf() calls with VNC_DEBUG ui: report error if user requests VNC option that is unsupported ui: split setup of VNC auth scheme into separate method ui: fix setup of VNC websockets auth scheme with TLS ui: enforce TLS when using websockets server ui: remove separate gnutls_session for websockets server ui: ensure VNC websockets server checks the ACL if requested Markus Armbruster (1): vnc: Fix QMP change not to use funky error class ui/vnc-auth-vencrypt.c | 1 - ui/vnc-tls.c | 72 +--- ui/vnc-tls.h | 7 -- ui/vnc-ws.c| 46 ui/vnc-ws.h| 2 +- ui/vnc.c | 289 + ui/vnc.h | 9 +- 7 files changed, 223 insertions(+), 203 deletions(-)
Re: [Qemu-devel] [PATCH 3/8] pci: Remove unused functions
On Mon, Mar 09, 2015 at 06:30:10PM +0100, Thomas Huth wrote: The functions pcie_ari_init(), pcie_cap_is_arifwd_enabled() and ich9_d2pbr_init() are completely unused and thus can be deleted. Signed-off-by: Thomas Huth th...@linux.vnet.ibm.com Cc: Michael S. Tsirkin m...@redhat.com Cc: Anthony Liguori aligu...@amazon.com Pls split this out to two patches. ARI might be useful in the future. ich9_d2pbr_init can go I think. --- hw/pci-bridge/i82801b11.c | 21 - hw/pci/pcie.c | 25 - include/hw/i386/ich9.h|1 - include/hw/pci/pcie.h |3 --- 4 files changed, 0 insertions(+), 50 deletions(-) diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c index 14cd7fd..7e79bc0 100644 --- a/hw/pci-bridge/i82801b11.c +++ b/hw/pci-bridge/i82801b11.c @@ -101,27 +101,6 @@ static const TypeInfo i82801b11_bridge_info = { .class_init= i82801b11_bridge_class_init, }; -PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus) -{ -PCIDevice *d; -PCIBridge *br; -char buf[16]; -DeviceState *qdev; - -d = pci_create_multifunction(bus, devfn, true, i82801b11-bridge); -if (!d) { -return NULL; -} -br = PCI_BRIDGE(d); -qdev = DEVICE(d); - -snprintf(buf, sizeof(buf), pci.%d, sec_bus); -pci_bridge_map_irq(br, buf, pci_swizzle_map_irq_fn); -qdev_init_nofail(qdev); - -return pci_bridge_get_sec_bus(br); -} - static void d2pbr_register(void) { type_register_static(i82801b11_bridge_info); diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 1a1..9b9f63d 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -515,19 +515,6 @@ void pcie_cap_arifwd_reset(PCIDevice *dev) pci_long_test_and_clear_mask(devctl2, PCI_EXP_DEVCTL2_ARI); } -bool pcie_cap_is_arifwd_enabled(const PCIDevice *dev) -{ -if (!pci_is_express(dev)) { -return false; -} -if (!dev-exp.exp_cap) { -return false; -} - -return pci_get_long(dev-config + dev-exp.exp_cap + PCI_EXP_DEVCTL2) -PCI_EXP_DEVCTL2_ARI; -} - /** * pci express extended capability list management functions * uint16_t ext_cap_id (16 bit) @@ -621,15 +608,3 @@ void pcie_add_capability(PCIDevice *dev, /* Check capability by default */ memset(dev-cmask + offset, 0xFF, size); } - -/** - * pci express extended capability helper functions - */ - -/* ARI */ -void pcie_ari_init(PCIDevice *dev, uint16_t offset, uint16_t nextfn) -{ -pcie_add_capability(dev, PCI_EXT_CAP_ID_ARI, PCI_ARI_VER, -offset, PCI_ARI_SIZEOF); -pci_set_long(dev-config + offset + PCI_ARI_CAP, (nextfn 0xff) 8); -} diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index 59ea25b..5cede9b 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -19,7 +19,6 @@ void ich9_lpc_set_irq(void *opaque, int irq_num, int level); int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx); PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin); void ich9_lpc_pm_init(PCIDevice *pci_lpc); -PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus); I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base); #define ICH9_CC_SIZE(16 * 1024) /* 16KB */ diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h index b48a7a2..ae0969a 100644 --- a/include/hw/pci/pcie.h +++ b/include/hw/pci/pcie.h @@ -106,7 +106,6 @@ void pcie_cap_flr_write_config(PCIDevice *dev, /* ARI forwarding capability and control */ void pcie_cap_arifwd_init(PCIDevice *dev); void pcie_cap_arifwd_reset(PCIDevice *dev); -bool pcie_cap_is_arifwd_enabled(const PCIDevice *dev); /* PCI express extended capability helper functions */ uint16_t pcie_find_capability(PCIDevice *dev, uint16_t cap_id); @@ -114,8 +113,6 @@ void pcie_add_capability(PCIDevice *dev, uint16_t cap_id, uint8_t cap_ver, uint16_t offset, uint16_t size); -void pcie_ari_init(PCIDevice *dev, uint16_t offset, uint16_t nextfn); - extern const VMStateDescription vmstate_pcie_device; #define VMSTATE_PCIE_DEVICE(_field, _state) {\ -- 1.7.1
Re: [Qemu-devel] [PATCH] migration: flush the bdrv before stopping VM
First explanation, why I think this don't fix the full problem. Whith this patch, we fix the problem where we have a dirty block layer but basically nothing dirtying the memory on the guest (we are moving the 20 seconds from max_downtime for the blocklayer flush), to 20 seconds until we have decided that the amount of dirty memory is small enough to be transferred during max_downtime. But it is still going to take 20 seconds to flush the block layer, and during that 20 seconds, the amount of memory that can be dirty is HUGE. It's true. What kind of cache is it actually that takes 20s to flush here? I run a script in the guest which do a dd operation, like this: #!/bin/sh for i in {1..100} do time dd if=/dev/zero of=/time.bdf bs=4k count=20 rm /time.bdf done It's an extreme case.
Re: [Qemu-devel] [PATCH] migration: flush the bdrv before stopping VM
Am 18.03.2015 um 13:36 hat Juan Quintela geschrieben: Kevin Wolf kw...@redhat.com wrote: The problem is that the block layer really doesn't have an option to control what is getting synced once the data is cached outside of qemu. Essentially we can do an fdatasync() or we can leave it, that's the only choice we have. See my explanation, if all that qemu is doing is an fdatasync(), just spawn a thread that do the fdatasync() and if the thread don't finish in timeout time, just return one error. You can implement that behaviour whatever you want. Yes, and if you use bdrv_co_flush(), this is one of the worker threads that raw-posix uses. So no new code to write for that. Now doing an asynchronous fdatasync() in the background is completely reasonable in order to reduce the amount of data to be flushed later. But the patch is doing it while holding both the BQL and the AIOContext lock of the device, which doesn't feel right. Maybe it should schedule a BH in the AIOContext instead and flush from there asynchronously. Position is wrong, definitelly. We want to start the asynchronous fdatasync() at the start of migration, or each X milliseconds. At this point, we *think* that we can finish the migration on max_downtime (basically we are ignoring the time that is going to take to migrate device state and do the block layer flush, but normally this takes in the other of 100-200ms, so it don't matter at all). The other thing is that flushing once doesn't mean that new data isn't accumulating in the cache, especially if you decide to do the background flush at the start of the migration. But pontentially, we would arrive to this point with less cached data everything on the system. The obvious way to avoid that would be to switch to a writethrough mode, so any write request goes directly to the disk. This will, however, impact performance so heavily that it's probably not a realistic option. An alternative approach could be to repeat the background flush periodically, either time based or after every x bytes that are written to a device. Time based should actually be quite easy to implement. We can do it periodically on the migration thread, if the call is thread_safe. We already have a loop there, and kind of time control, what we miss is an interface. Don't do it from the migration thread. You'd have to take locks and stop the guest from doing I/O while the flush is running. Instead, create a coroutine and use a BH to enter it from the main loop of the AIOContext of the block device (i.e. the qemu main loop thread in most cases, or the dataplane thread if it exists). Then your flush will run in the background without blocking anyone else. Time control in coroutines is as easy as calling co_aio_sleep_ns(). Once we have the flushing in the background, the migration code can apply any timeouts it wants. If the timeout is exceeded, the flush wouldn't be aborted but keep running in the background, but migration can go back to the iterative state anyway. Yeap, that is what we really want/need. Cool. I don't think it's very hard to get there. Notice that my understanding is that any proper fix for this is 2.4 material. Yes, I agree. Kevin
Re: [Qemu-devel] [PATCH] migration: flush the bdrv before stopping VM
Kevin Wolf kw...@redhat.com wrote: [ Cc: qemu-block ] Am 18.03.2015 um 04:19 hat Li, Liang Z geschrieben: This needs further review/changes on the block layer. First explanation, why I think this don't fix the full problem. Whith this patch, we fix the problem where we have a dirty block layer but basically nothing dirtying the memory on the guest (we are moving the 20 seconds from max_downtime for the blocklayer flush), to 20 seconds until we have decided that the amount of dirty memory is small enough to be transferred during max_downtime. But it is still going to take 20 seconds to flush the block layer, and during that 20 seconds, the amount of memory that can be dirty is HUGE. It's true. What kind of cache is it actually that takes 20s to flush here? That is a very good question. When I meassured this (long, long ago), testing with the same workload, bdrv_flush_all() could take form 100-300ms (what I expected and I can live with that), to several seconds, what I can't live with. Basically (this was around RHEL6 times, whatever upstream were there at the time), my notes of the time point to: aio.c:quemu_aio_wait() . ret = select(max_fd, rdfds, wrfds, NULL, NULL); notice that we are doing a select without a timeout in the iothread, bad. I know that the code has changed a lot on that area, the select() don't exist anymore. But this exemplifies the problem, something asks the block layer to do an operation, and it blocks until it finishes, even if this time it is taking more than usual for whatever reason. What I would really is a way to be able to bdrv_flush_all() to take a timeout parameter and return an error case that it is taking too long. Inside of qemu, we don't cache a whole lot. If you use qcow2, we do use a writeback cache for some metadata that might need to be written back, but it is small and shouldn't take any significant time. Then we have the kernel page cache, or for some network protocols caches in the respective libs. This sounds like the right size for a 20s stall, but don't we require cache.direct=on for live migration anyway for coherency, i.e. bypassing any such cache? Lastly there may be a disk cache, but it's too small either. I think our ouptions are: - tell the block layer at the beggining of migration Hey, we are migrating, could you please start flusing data now, and don't get the caches to grow too much, please, pretty please. (I left the API to the block layer) - Add on that point a new function: bdrvr_flush_all_start() That starts the sending of pages, and we hope that by the time that we have migrated all memory, they have also finished (so our last call to block_flush_all() have less work to do) - Add another function: int bdrv_flush_all_timeout(int timeout) that returns if timeout pass, telling if it has migrated all pages or timeout has passed. So we can got back to the iterative stage if it has taken too long. The problem is that the block layer really doesn't have an option to control what is getting synced once the data is cached outside of qemu. Essentially we can do an fdatasync() or we can leave it, that's the only choice we have. See my explanation, if all that qemu is doing is an fdatasync(), just spawn a thread that do the fdatasync() and if the thread don't finish in timeout time, just return one error. You can implement that behaviour whatever you want. Now doing an asynchronous fdatasync() in the background is completely reasonable in order to reduce the amount of data to be flushed later. But the patch is doing it while holding both the BQL and the AIOContext lock of the device, which doesn't feel right. Maybe it should schedule a BH in the AIOContext instead and flush from there asynchronously. Position is wrong, definitelly. We want to start the asynchronous fdatasync() at the start of migration, or each X milliseconds. At this point, we *think* that we can finish the migration on max_downtime (basically we are ignoring the time that is going to take to migrate device state and do the block layer flush, but normally this takes in the other of 100-200ms, so it don't matter at all). The other thing is that flushing once doesn't mean that new data isn't accumulating in the cache, especially if you decide to do the background flush at the start of the migration. But pontentially, we would arrive to this point with less cached data everything on the system. The obvious way to avoid that would be to switch to a writethrough mode, so any write request goes directly to the disk. This will, however, impact performance so heavily that it's probably not a realistic option. An alternative approach could be to repeat the background flush periodically, either time based or after every x bytes that are written to a device. Time based should actually be quite easy to implement. We can do it periodically on
[Qemu-devel] [PULL 4/8] aer: fix wrong check on expose aer tlp prefix log
From: Chen Fan chen.fan.f...@cn.fujitsu.com when specify TLP Prefix log as using pcie_aer_inject_error, the TLP prefix log is always discarded. because the check is incorrect, the End-End TLP Prefix Supported bit (PCI_EXP_DEVCAP2_EETLPP) should be in Device Capabilities 2 Register. Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/pci/pcie_aer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c index 5a25c32..c7fad34 100644 --- a/hw/pci/pcie_aer.c +++ b/hw/pci/pcie_aer.c @@ -433,7 +433,7 @@ static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err) } if ((err-flags PCIE_AER_ERR_TLP_PREFIX_PRESENT) -(pci_get_long(dev-config + dev-exp.exp_cap + PCI_EXP_DEVCTL2) +(pci_get_long(dev-config + dev-exp.exp_cap + PCI_EXP_DEVCAP2) PCI_EXP_DEVCAP2_EETLPP)) { for (i = 0; i ARRAY_SIZE(err-prefix); ++i) { /* 7.10.12 tlp prefix log register */ -- MST
[Qemu-devel] [PULL 5/8] pcie_aer: fix typos in pcie_aer_inject_error comment
From: Chen Fan chen.fan.f...@cn.fujitsu.com Refer to PCI Express Base Spec3.0, this comments can't fit the description in spec, so we should fix them. Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/pci/pcie_aer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c index c7fad34..9daebc2 100644 --- a/hw/pci/pcie_aer.c +++ b/hw/pci/pcie_aer.c @@ -618,11 +618,11 @@ static bool pcie_aer_inject_uncor_error(PCIEAERInject *inj, bool is_fatal) * non-Function specific error must be recorded in all functions. * It is the responsibility of the caller of this function. * It is also caller's responsibility to determine which function should - * report the rerror. + * report the error. * * 6.2.4 Error Logging - * 6.2.5 Sqeunce of Device Error Signaling and Logging Operations - * table 6-2: Flowchard Showing Sequence of Device Error Signaling and Logging + * 6.2.5 Sequence of Device Error Signaling and Logging Operations + * table 6-2: Flowchart Showing Sequence of Device Error Signaling and Logging *Operations */ int pcie_aer_inject_error(PCIDevice *dev, const PCIEAERErr *err) -- MST
Re: [Qemu-devel] [PATCH V4 07/19] virtio-net: validate backend queue numbers against bus limitation
On Wed, Mar 18, 2015 at 05:34:57PM +0800, Jason Wang wrote: We don't validate the backend queue numbers against bus limitation, this will easily crash qemu if it exceeds the limitation. Fixing this by doing the validation and fail early. Cc: Michael S. Tsirkin m...@redhat.com Signed-off-by: Jason Wang jasow...@redhat.com Bugfix? needed in 2.3? --- hw/net/virtio-net.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 27adcc5..59f76bc 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1588,6 +1588,13 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) virtio_init(vdev, virtio-net, VIRTIO_ID_NET, n-config_size); n-max_queues = MAX(n-nic_conf.peers.queues, 1); +if (n-max_queues * 2 + 1 VIRTIO_PCI_QUEUE_MAX) { We have this * 2 + 1 logic in several other places in this file too. Pls wrap it up in a helper. +error_setg(errp, Invalid number of queues (= % PRIu32 ), + must be a postive integer less than %d., + n-max_queues, (VIRTIO_PCI_QUEUE_MAX - 1) / 2); +virtio_cleanup(vdev); +return; +} n-vqs = g_malloc0(sizeof(VirtIONetQueue) * n-max_queues); n-vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx); n-curr_queues = 1; -- 2.1.0
[Qemu-devel] [PULL 04/13] uhci: Convert to realize
From: Markus Armbruster arm...@redhat.com Signed-off-by: Markus Armbruster arm...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/usb/hcd-uhci.c | 18 -- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 2ca8de3..e791377 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -66,7 +66,7 @@ struct UHCIInfo { uint16_t device_id; uint8_trevision; uint8_tirq_pin; -int(*initfn)(PCIDevice *dev); +void (*realize)(PCIDevice *dev, Error **errp); bool unplug; }; @@ -1190,7 +1190,7 @@ static USBPortOps uhci_port_ops = { static USBBusOps uhci_bus_ops = { }; -static int usb_uhci_common_initfn(PCIDevice *dev) +static void usb_uhci_common_realize(PCIDevice *dev, Error **errp) { Error *err = NULL; PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); @@ -1215,8 +1215,8 @@ static int usb_uhci_common_initfn(PCIDevice *dev) USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL, err); if (err) { -error_report_err(err); -return -1; +error_propagate(errp, err); +return; } } else { usb_bus_new(s-bus, sizeof(s-bus), uhci_bus_ops, DEVICE(dev)); @@ -1238,11 +1238,9 @@ static int usb_uhci_common_initfn(PCIDevice *dev) /* Use region 4 for consistency with real hardware. BSD guests seem to rely on this. */ pci_register_bar(s-dev, 4, PCI_BASE_ADDRESS_SPACE_IO, s-io_bar); - -return 0; } -static int usb_uhci_vt82c686b_initfn(PCIDevice *dev) +static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp) { UHCIState *s = DO_UPCAST(UHCIState, dev, dev); uint8_t *pci_conf = s-dev.config; @@ -1254,7 +1252,7 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev) /* USB legacy support */ pci_set_long(pci_conf + 0xc0,0x2000); -return usb_uhci_common_initfn(dev); +usb_uhci_common_realize(dev, errp); } static void usb_uhci_exit(PCIDevice *dev) @@ -1300,7 +1298,7 @@ static void uhci_class_init(ObjectClass *klass, void *data) UHCIPCIDeviceClass *u = container_of(k, UHCIPCIDeviceClass, parent_class); UHCIInfo *info = data; -k-init = info-initfn ? info-initfn : usb_uhci_common_initfn; +k-realize = info-realize ? info-realize : usb_uhci_common_realize; k-exit = info-unplug ? usb_uhci_exit : NULL; k-vendor_id = info-vendor_id; k-device_id = info-device_id; @@ -1339,7 +1337,7 @@ static UHCIInfo uhci_info[] = { .device_id = PCI_DEVICE_ID_VIA_UHCI, .revision = 0x01, .irq_pin = 3, -.initfn= usb_uhci_vt82c686b_initfn, +.realize = usb_uhci_vt82c686b_realize, .unplug= true, },{ .name = ich9-usb-uhci1, /* 00:1d.0 */ -- 1.8.3.1
[Qemu-devel] [PULL 13/13] ehci: fix segfault when hot-unplugging ehci controller
From: Gonglei arei.gong...@huawei.com When hot-unplugging the usb controllers (ehci/uhci), we have to clean all resouce of these devices, involved registered reset handler. Otherwise, it may cause NULL pointer access and/or segmentation fault if we reboot the guest os after hot-unplugging. Let's hook up reset via DeviceClass-reset() and drop the qemu_register_reset() call. Then Qemu will register and unregister the reset handler automatically. Cc: qemu-stable qemu-sta...@nongnu.org Reported-by: Lidonglin lidong...@huawei.com Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/usb/hcd-ehci-pci.c| 10 ++ hw/usb/hcd-ehci-sysbus.c | 10 ++ hw/usb/hcd-ehci.c| 3 +-- hw/usb/hcd-ehci.h| 1 + 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c index 4c80707..7afa5f9 100644 --- a/hw/usb/hcd-ehci-pci.c +++ b/hw/usb/hcd-ehci-pci.c @@ -101,6 +101,15 @@ static void usb_ehci_pci_exit(PCIDevice *dev) } } +static void usb_ehci_pci_reset(DeviceState *dev) +{ +PCIDevice *pci_dev = PCI_DEVICE(dev); +EHCIPCIState *i = PCI_EHCI(pci_dev); +EHCIState *s = i-ehci; + +ehci_reset(s); +} + static void usb_ehci_pci_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int l) { @@ -143,6 +152,7 @@ static void ehci_class_init(ObjectClass *klass, void *data) k-config_write = usb_ehci_pci_write_config; dc-vmsd = vmstate_ehci_pci; dc-props = ehci_pci_properties; +dc-reset = usb_ehci_pci_reset; } static const TypeInfo ehci_pci_type_info = { diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c index 19ed2c2..cd1cc14 100644 --- a/hw/usb/hcd-ehci-sysbus.c +++ b/hw/usb/hcd-ehci-sysbus.c @@ -42,6 +42,15 @@ static void usb_ehci_sysbus_realize(DeviceState *dev, Error **errp) sysbus_init_irq(d, s-irq); } +static void usb_ehci_sysbus_reset(DeviceState *dev) +{ +SysBusDevice *d = SYS_BUS_DEVICE(dev); +EHCISysBusState *i = SYS_BUS_EHCI(d); +EHCIState *s = i-ehci; + +ehci_reset(s); +} + static void ehci_sysbus_init(Object *obj) { SysBusDevice *d = SYS_BUS_DEVICE(obj); @@ -70,6 +79,7 @@ static void ehci_sysbus_class_init(ObjectClass *klass, void *data) dc-realize = usb_ehci_sysbus_realize; dc-vmsd = vmstate_ehci_sysbus; dc-props = ehci_sysbus_properties; +dc-reset = usb_ehci_sysbus_reset; set_bit(DEVICE_CATEGORY_USB, dc-categories); } diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 5c2a452..d4d7547 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -839,7 +839,7 @@ static USBDevice *ehci_find_device(EHCIState *ehci, uint8_t addr) } /* 4.1 host controller initialization */ -static void ehci_reset(void *opaque) +void ehci_reset(void *opaque) { EHCIState *s = opaque; int i; @@ -2465,7 +2465,6 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) s-async_bh = qemu_bh_new(ehci_frame_timer, s); s-device = dev; -qemu_register_reset(ehci_reset, s); s-vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s); } diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index 2bc259c..87b240f 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -325,6 +325,7 @@ extern const VMStateDescription vmstate_ehci; void usb_ehci_init(EHCIState *s, DeviceState *dev); void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp); void usb_ehci_unrealize(EHCIState *s, DeviceState *dev, Error **errp); +void ehci_reset(void *opaque); #define TYPE_PCI_EHCI pci-ehci-usb #define PCI_EHCI(obj) OBJECT_CHECK(EHCIPCIState, (obj), TYPE_PCI_EHCI) -- 1.8.3.1
[Qemu-devel] [PULL 1/9] vnc: Fix QMP change not to use funky error class
From: Markus Armbruster arm...@redhat.com Error classes are a leftover from the days of rich error objects. New code should always use ERROR_CLASS_GENERIC_ERROR. Commit 1d0d59f added a use of ERROR_CLASS_DEVICE_NOT_FOUND. Replace it. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/vnc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/vnc.c b/ui/vnc.c index 6f9b718..a950016 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3594,7 +3594,7 @@ void vnc_display_open(const char *id, Error **errp) dev = qdev_find_recursive(sysbus_get_default(), device_id); if (dev == NULL) { -error_set(errp, QERR_DEVICE_NOT_FOUND, device_id); +error_setg(errp, Device '%s' not found, device_id); goto fail; } -- 1.8.3.1
[Qemu-devel] [PULL 6/9] ui: fix setup of VNC websockets auth scheme with TLS
From: Daniel P. Berrange berra...@redhat.com The way the websockets TLS code was integrated into the VNC server made it essentially useless. The only time that the websockets TLS support could be used is if the primary VNC server had its existing TLS support disabled. ie QEMU had to be launched with: # qemu -vnc localhost:1,websockets=5902,x509=/path/to/certs Note the absence of the 'tls' flag. This is already a bug, because the docs indicate that 'x509' is ignored unless 'tls' is given. If the primary VNC server had TLS turned on via the 'tls' flag, then this prevented the websockets TLS support from being used, because it activates the VeNCrypt auth which would have resulted in TLS being run over a TLS session. Of course no websockets VNC client supported VeNCrypt so in practice, since the browser clients cannot setup a nested TLS session over the main HTTPS connection, so it would not even get past auth. This patch causes us to decide our auth scheme separately for the main VNC server vs the websockets VNC server. We take account of the fact that if TLS is enabled, then the websockets client will use https, so setting up VeNCrypt is thus redundant as it would lead to nested TLS sessions. Signed-off-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/vnc.c | 55 ++- ui/vnc.h | 2 ++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 8edbb67..7b66f93 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3012,9 +3012,16 @@ static void vnc_connect(VncDisplay *vd, int csock, vs-auth = VNC_AUTH_NONE; vs-subauth = VNC_AUTH_INVALID; } else { - vs-auth = vd-auth; - vs-subauth = vd-subauth; +if (websocket) { +vs-auth = vd-ws_auth; +vs-subauth = VNC_AUTH_INVALID; +} else { +vs-auth = vd-auth; +vs-subauth = vd-subauth; +} } +VNC_DEBUG(Client sock=%d ws=%d auth=%d subauth=%d\n, + csock, websocket, vs-auth, vs-subauth); vs-lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs-lossy_rect)); for (i = 0; i VNC_STAT_ROWS; ++i) { @@ -3028,7 +3035,7 @@ static void vnc_connect(VncDisplay *vd, int csock, if (websocket) { vs-websocket = 1; #ifdef CONFIG_VNC_TLS -if (vd-tls.x509cert) { +if (vd-ws_tls) { qemu_set_fd_handler2(vs-csock, NULL, vncws_tls_handshake_peek, NULL, vs); } else @@ -3320,7 +3327,8 @@ vnc_display_setup_auth(VncDisplay *vs, bool password, bool sasl, bool tls, - bool x509) + bool x509, + bool websocket) { /* * We have a choice of 3 authentication options @@ -3355,10 +3363,26 @@ vnc_display_setup_auth(VncDisplay *vs, * in an appropriate manner. In regular VNC, all the * TLS options get mapped into VNC_AUTH_VENCRYPT * sub-auth types. + * + * In websockets, the https:// protocol already provides + * TLS support, so there is no need to make use of the + * VeNCrypt extension. Furthermore, websockets browser + * clients could not use VeNCrypt even if they wanted to, + * as they cannot control when the TLS handshake takes + * place. Thus there is no option but to rely on https://, + * meaning combinations 4-6 and 7-9 will be mapped to + * VNC auth schemes in the same way as combos 1-3. + * + * Regardless of fact that we have a different mapping to + * VNC auth mechs for plain VNC vs websockets VNC, the end + * result has the same security characteristics. */ if (password) { if (tls) { vs-auth = VNC_AUTH_VENCRYPT; +if (websocket) { +vs-ws_tls = true; +} if (x509) { VNC_DEBUG(Initializing VNC server with x509 password auth\n); vs-subauth = VNC_AUTH_VENCRYPT_X509VNC; @@ -3371,9 +3395,17 @@ vnc_display_setup_auth(VncDisplay *vs, vs-auth = VNC_AUTH_VNC; vs-subauth = VNC_AUTH_INVALID; } +if (websocket) { +vs-ws_auth = VNC_AUTH_VNC; +} else { +vs-ws_auth = VNC_AUTH_INVALID; +} } else if (sasl) { if (tls) { vs-auth = VNC_AUTH_VENCRYPT; +if (websocket) { +vs-ws_tls = true; +} if (x509) { VNC_DEBUG(Initializing VNC server with x509 SASL auth\n); vs-subauth = VNC_AUTH_VENCRYPT_X509SASL; @@ -3386,9 +3418,17 @@ vnc_display_setup_auth(VncDisplay *vs, vs-auth = VNC_AUTH_SASL; vs-subauth = VNC_AUTH_INVALID; } +if (websocket) { +vs-ws_auth = VNC_AUTH_SASL; +} else { +vs-ws_auth =
[Qemu-devel] [PULL 8/9] ui: remove separate gnutls_session for websockets server
From: Daniel P. Berrange berra...@redhat.com The previous change to the auth scheme handling guarantees we can never have nested TLS sessions in the VNC websockets server. Thus we can remove the separate gnutls_session instance. Signed-off-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/vnc-tls.c | 70 +--- ui/vnc-ws.c | 4 ++-- ui/vnc.c | 18 ++-- ui/vnc.h | 3 --- 4 files changed, 33 insertions(+), 62 deletions(-) diff --git a/ui/vnc-tls.c b/ui/vnc-tls.c index de1cb34..eddd39b 100644 --- a/ui/vnc-tls.c +++ b/ui/vnc-tls.c @@ -334,82 +334,77 @@ 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 (tls-session == NULL) { -if (gnutls_init(tls-session, GNUTLS_SERVER) 0) { +if (vs-tls.session == NULL) { +if (gnutls_init(vs-tls.session, GNUTLS_SERVER) 0) { vnc_client_error(vs); return -1; } -if (gnutls_set_default_priority(tls-session) 0) { -gnutls_deinit(tls-session); -tls-session = NULL; +if (gnutls_set_default_priority(vs-tls.session) 0) { +gnutls_deinit(vs-tls.session); +vs-tls.session = NULL; vnc_client_error(vs); return -1; } -if (vnc_set_gnutls_priority(tls-session, needX509Creds) 0) { -gnutls_deinit(tls-session); -tls-session = NULL; +if (vnc_set_gnutls_priority(vs-tls.session, needX509Creds) 0) { +gnutls_deinit(vs-tls.session); +vs-tls.session = NULL; vnc_client_error(vs); return -1; } if (needX509Creds) { -gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs-vd); +gnutls_certificate_server_credentials x509_cred = +vnc_tls_initialize_x509_cred(vs-vd); if (!x509_cred) { -gnutls_deinit(tls-session); -tls-session = NULL; +gnutls_deinit(vs-tls.session); +vs-tls.session = NULL; vnc_client_error(vs); return -1; } -if (gnutls_credentials_set(tls-session, GNUTLS_CRD_CERTIFICATE, x509_cred) 0) { -gnutls_deinit(tls-session); -tls-session = NULL; +if (gnutls_credentials_set(vs-tls.session, + GNUTLS_CRD_CERTIFICATE, x509_cred) 0) { +gnutls_deinit(vs-tls.session); +vs-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 (tls-session, GNUTLS_CERT_REQUEST); +gnutls_certificate_server_set_request(vs-tls.session, + GNUTLS_CERT_REQUEST); } } else { -gnutls_anon_server_credentials_t anon_cred = vnc_tls_initialize_anon_cred(); +gnutls_anon_server_credentials_t anon_cred = +vnc_tls_initialize_anon_cred(); if (!anon_cred) { -gnutls_deinit(tls-session); -tls-session = NULL; +gnutls_deinit(vs-tls.session); +vs-tls.session = NULL; vnc_client_error(vs); return -1; } -if (gnutls_credentials_set(tls-session, GNUTLS_CRD_ANON, anon_cred) 0) { -gnutls_deinit(tls-session); -tls-session = NULL; +if (gnutls_credentials_set(vs-tls.session, + GNUTLS_CRD_ANON, anon_cred) 0) { +gnutls_deinit(vs-tls.session); +vs-tls.session = NULL; gnutls_anon_free_server_credentials(anon_cred); vnc_client_error(vs); return -1; } } -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); +gnutls_transport_set_ptr(vs-tls.session, (gnutls_transport_ptr_t)vs); +
[Qemu-devel] [PATCH 6/8] exec: mark unassigned_io_ops as unlocked
Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- exec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/exec.c b/exec.c index d60abfc..c1a2e9e 100644 --- a/exec.c +++ b/exec.c @@ -2197,6 +2197,7 @@ static void memory_map_init(void) system_io = g_malloc(sizeof(*system_io)); memory_region_init_io(system_io, NULL, unassigned_io_ops, NULL, io, 65536); +memory_region_clear_global_locking(system_io); address_space_init(address_space_io, system_io, I/O); memory_listener_register(core_memory_listener, address_space_memory); -- 2.3.0
[Qemu-devel] [PULL 4/9] ui: report error if user requests VNC option that is unsupported
From: Daniel P. Berrange berra...@redhat.com If the VNC server is built without tls, sasl or websocket support and the user requests one of these features, they are just silently ignored. This is bad because it means the VNC server ends up running in a configuration that is less secure than the user asked for. It also leads to an tangled mass of preprocessor conditionals when configuring the VNC server. This ensures that the tls, sasl websocket options are always processed and an error is reported back to the user if any of them were disabled at build time. Signed-off-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/vnc.c | 51 +-- ui/vnc.h | 4 ++-- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 6f0b0ce..d5e6024 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3010,14 +3010,10 @@ static void vnc_connect(VncDisplay *vd, int csock, if (skipauth) { vs-auth = VNC_AUTH_NONE; -#ifdef CONFIG_VNC_TLS vs-subauth = VNC_AUTH_INVALID; -#endif } else { vs-auth = vd-auth; -#ifdef CONFIG_VNC_TLS vs-subauth = vd-subauth; -#endif } vs-lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs-lossy_rect)); @@ -3206,8 +3202,8 @@ static void vnc_display_close(VncDisplay *vs) } #endif /* CONFIG_VNC_WS */ vs-auth = VNC_AUTH_INVALID; -#ifdef CONFIG_VNC_TLS vs-subauth = VNC_AUTH_INVALID; +#ifdef CONFIG_VNC_TLS vs-tls.x509verify = 0; #endif } @@ -3332,15 +3328,13 @@ void vnc_display_open(const char *id, Error **errp) char *h; bool has_ipv4 = false; bool has_ipv6 = false; -#ifdef CONFIG_VNC_WS const char *websocket; -#endif -#ifdef CONFIG_VNC_TLS bool tls = false, x509 = false; +#ifdef CONFIG_VNC_TLS const char *path; #endif -#ifdef CONFIG_VNC_SASL bool sasl = false; +#ifdef CONFIG_VNC_SASL int saslErr; #endif #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL) @@ -3404,11 +3398,15 @@ void vnc_display_open(const char *id, Error **errp) reverse = qemu_opt_get_bool(opts, reverse, false); lock_key_sync = qemu_opt_get_bool(opts, lock-key-sync, true); -#ifdef CONFIG_VNC_SASL sasl = qemu_opt_get_bool(opts, sasl, false); -#endif -#ifdef CONFIG_VNC_TLS +#ifndef CONFIG_VNC_SASL +if (sasl) { +error_setg(errp, VNC SASL auth requires cyrus-sasl support); +goto fail; +} +#endif /* CONFIG_VNC_SASL */ tls = qemu_opt_get_bool(opts, tls, false); +#ifdef CONFIG_VNC_TLS path = qemu_opt_get(opts, x509); if (!path) { path = qemu_opt_get(opts, x509verify); @@ -3424,7 +3422,12 @@ void vnc_display_open(const char *id, Error **errp) goto fail; } } -#endif +#else /* ! CONFIG_VNC_TLS */ +if (tls) { +error_setg(errp, VNC TLS auth requires gnutls support); +goto fail; +} +#endif /* ! CONFIG_VNC_TLS */ #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL) acl = qemu_opt_get_bool(opts, acl, false); #endif @@ -3446,14 +3449,16 @@ void vnc_display_open(const char *id, Error **errp) } vs-connections_limit = qemu_opt_get_number(opts, connections, 32); - #ifdef CONFIG_VNC_WS websocket = qemu_opt_get(opts, websocket); if (websocket) { +#ifdef CONFIG_VNC_WS vs-ws_enabled = true; qemu_opt_set(wsopts, port, websocket, error_abort); - +#else /* ! CONFIG_VNC_WS */ +error_setg(errp, Websockets protocol requires gnutls support); +goto fail; +#endif /* ! CONFIG_VNC_WS */ } -#endif /* CONFIG_VNC_WS */ #ifdef CONFIG_VNC_JPEG vs-lossy = qemu_opt_get_bool(opts, lossy, false); @@ -3518,7 +3523,6 @@ void vnc_display_open(const char *id, Error **errp) * NB2. the x509 schemes have option to validate a client cert dname */ if (password) { -#ifdef CONFIG_VNC_TLS if (tls) { vs-auth = VNC_AUTH_VENCRYPT; if (x509) { @@ -3529,16 +3533,11 @@ void vnc_display_open(const char *id, Error **errp) vs-subauth = VNC_AUTH_VENCRYPT_TLSVNC; } } else { -#endif /* CONFIG_VNC_TLS */ VNC_DEBUG(Initializing VNC server with password auth\n); vs-auth = VNC_AUTH_VNC; -#ifdef CONFIG_VNC_TLS vs-subauth = VNC_AUTH_INVALID; } -#endif /* CONFIG_VNC_TLS */ -#ifdef CONFIG_VNC_SASL } else if (sasl) { -#ifdef CONFIG_VNC_TLS if (tls) { vs-auth = VNC_AUTH_VENCRYPT; if (x509) { @@ -3549,16 +3548,11 @@ void vnc_display_open(const char *id, Error **errp) vs-subauth = VNC_AUTH_VENCRYPT_TLSSASL; } } else { -#endif /* CONFIG_VNC_TLS */ VNC_DEBUG(Initializing VNC server with SASL auth\n); vs-auth = VNC_AUTH_SASL; -#ifdef CONFIG_VNC_TLS vs-subauth = VNC_AUTH_INVALID; } -#endif /* CONFIG_VNC_TLS */ -#endif /*
[Qemu-devel] [PULL 2/8] virtio: Fix memory leaks reported by Coverity
From: Stefan Weil s...@weilnetz.de All four leaks are similar, so fix them in one patch. Signed-off-by: Stefan Weil s...@weilnetz.de Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/9pfs/virtio-9p-local.c | 28 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index d05c917..d66abcd 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -488,7 +488,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, int err = -1; int serrno = 0; V9fsString fullname; -char *buffer; +char *buffer = NULL; v9fs_string_init(fullname); v9fs_string_sprintf(fullname, %s/%s, dir_path-data, name); @@ -499,7 +499,6 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, buffer = rpath(fs_ctx, path); err = mknod(buffer, SM_LOCAL_MODE_BITS|S_IFREG, 0); if (err == -1) { -g_free(buffer); goto out; } err = local_set_xattr(buffer, credp); @@ -512,7 +511,6 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, buffer = rpath(fs_ctx, path); err = mknod(buffer, SM_LOCAL_MODE_BITS|S_IFREG, 0); if (err == -1) { -g_free(buffer); goto out; } err = local_set_mapped_file_attr(fs_ctx, path, credp); @@ -525,7 +523,6 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, buffer = rpath(fs_ctx, path); err = mknod(buffer, credp-fc_mode, credp-fc_rdev); if (err == -1) { -g_free(buffer); goto out; } err = local_post_create_passthrough(fs_ctx, path, credp); @@ -539,8 +536,8 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, err_end: remove(buffer); errno = serrno; -g_free(buffer); out: +g_free(buffer); v9fs_string_free(fullname); return err; } @@ -552,7 +549,7 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, int err = -1; int serrno = 0; V9fsString fullname; -char *buffer; +char *buffer = NULL; v9fs_string_init(fullname); v9fs_string_sprintf(fullname, %s/%s, dir_path-data, name); @@ -563,7 +560,6 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, buffer = rpath(fs_ctx, path); err = mkdir(buffer, SM_LOCAL_DIR_MODE_BITS); if (err == -1) { -g_free(buffer); goto out; } credp-fc_mode = credp-fc_mode|S_IFDIR; @@ -576,7 +572,6 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, buffer = rpath(fs_ctx, path); err = mkdir(buffer, SM_LOCAL_DIR_MODE_BITS); if (err == -1) { -g_free(buffer); goto out; } credp-fc_mode = credp-fc_mode|S_IFDIR; @@ -590,7 +585,6 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, buffer = rpath(fs_ctx, path); err = mkdir(buffer, credp-fc_mode); if (err == -1) { -g_free(buffer); goto out; } err = local_post_create_passthrough(fs_ctx, path, credp); @@ -604,8 +598,8 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, err_end: remove(buffer); errno = serrno; -g_free(buffer); out: +g_free(buffer); v9fs_string_free(fullname); return err; } @@ -659,7 +653,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, int err = -1; int serrno = 0; V9fsString fullname; -char *buffer; +char *buffer = NULL; /* * Mark all the open to not follow symlinks @@ -675,7 +669,6 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, buffer = rpath(fs_ctx, path); fd = open(buffer, flags, SM_LOCAL_MODE_BITS); if (fd == -1) { -g_free(buffer); err = fd; goto out; } @@ -690,7 +683,6 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, buffer = rpath(fs_ctx, path); fd = open(buffer, flags, SM_LOCAL_MODE_BITS); if (fd == -1) { -g_free(buffer); err = fd; goto out; } @@ -706,7 +698,6 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, buffer = rpath(fs_ctx, path); fd = open(buffer, flags, credp-fc_mode); if (fd == -1) { -g_free(buffer); err = fd; goto out; } @@ -724,8 +715,8 @@ err_end: close(fd); remove(buffer); errno = serrno; -g_free(buffer); out: +g_free(buffer); v9fs_string_free(fullname); return err; } @@ -738,7 +729,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath, int serrno = 0; char
[Qemu-devel] [PULL 8/8] pcie_aer: fix comment to match pcie spec
Code comment says table 6-2 but in fact it's is not a table, it is Figure 6-2 on page 479. Cc: Chen Fan chen.fan.f...@cn.fujitsu.com Reported-by: Michael Tokarev m...@tls.msk.ru Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/pci/pcie_aer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c index 9126058..eaa3e6e 100644 --- a/hw/pci/pcie_aer.c +++ b/hw/pci/pcie_aer.c @@ -622,8 +622,8 @@ static bool pcie_aer_inject_uncor_error(PCIEAERInject *inj, bool is_fatal) * * 6.2.4 Error Logging * 6.2.5 Sequence of Device Error Signaling and Logging Operations - * table 6-2: Flowchart Showing Sequence of Device Error Signaling and Logging - *Operations + * Figure 6-2: Flowchart Showing Sequence of Device Error Signaling and Logging + * Operations */ int pcie_aer_inject_error(PCIDevice *dev, const PCIEAERErr *err) { -- MST
Re: [Qemu-devel] [RFC PATCH] cpus: Don't kick un-inited cpus.
On 18/03/2015 13:53, Peter Crosthwaite wrote: following a464982499b2f637f6699e3d03e0a9d2e0b5288b, it's now possible for there to be attempts to take the BQL before CPUs have been realized in cases where a machine model inits peripherals before the first CPU. BQL lock aquisition kicks the first_cpu, leading to a segfault if this happens pre-realize. Guard the CPU kick routine to perform no action for a CPU that doesn't exist or doesn't have a thread yet. Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- cpus.c | 4 1 file changed, 4 insertions(+) diff --git a/cpus.c b/cpus.c index 1ce90a1..c90dfa8 100644 --- a/cpus.c +++ b/cpus.c @@ -1046,6 +1046,10 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) static void qemu_cpu_kick_thread(CPUState *cpu) { +if (!cpu || !cpu-thread) { +return; +} + #ifndef _WIN32 int err; That's been fixed already for a couple of weeks. :) commit 21618b3e55ad2c6fede0bffcaea466091811ce59 Author: Paolo Bonzini pbonz...@redhat.com Date: Fri Feb 27 20:01:03 2015 +0100 cpus: be more paranoid in avoiding deadlocks For good measure, ensure that the following sequence: thread 1 calls qemu_mutex_lock_iothread thread 2 calls qemu_mutex_lock_iothread VCPU thread are created VCPU thread enters execution loop results in the VCPU threads letting the other two threads run and obeying iothread_requesting_mutex even if the VCPUs are not halted. To do this, check iothread_requesting_mutex before execution starts. Tested-by: Leon Alrae leon.al...@imgtec.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com commit 6b49809c597331803ea941eadda813e5bb4e8fe2 Author: Paolo Bonzini pbonz...@redhat.com Date: Fri Feb 27 19:58:23 2015 +0100 cpus: fix deadlock and segfault in qemu_mutex_lock_iothread When two threads (other than the low-priority TCG VCPU thread) are competing for the iothread lock, a deadlock can happen. This is because iothread_requesting_mutex is set to false by the first thread that gets the mutex, and then the VCPU thread might never yield from the execution loop. If iothread_requesting_mutex is changed from a bool to a counter, the deadlock is fixed. However, there is another bug in qemu_mutex_lock_iothread that can be triggered by the new call_rcu thread. The bug happens if qemu_mutex_lock_iothread is called before the CPUs are created. In that case, first_cpu is NULL and the caller segfaults in qemu_mutex_lock_iothread. To fix this, just do not do the kick if first_cpu is NULL. Reported-by: Leon Alrae leon.al...@imgtec.com Reported-by: Andreas Gustafsson g...@gson.org Tested-by: Leon Alrae leon.al...@imgtec.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com
[Qemu-devel] [PATCH for-2.4 0/8] memory: enable unlocked PIO/MMIO in KVM
And here we are... These are the changes required to make the BQL optional for memory access, and use that support in KVM. For now, only one device model is changed to do unlocked accesses. Please review! Jan Kiszka (4): memory: Add global-locking property to memory regions memory: Provide address_space_rw_unlocked kvm: First step to push iothread lock out of inner run loop kvm: Switch to unlocked PIO Paolo Bonzini (4): exec: move rcu_read_lock/unlock to address_space_translate callers exec: mark unassigned_io_ops as unlocked acpi: mark PMTIMER as unlocked kvm: Switch to unlocked MMIO exec.c| 75 ++- hw/acpi/core.c| 1 + hw/vfio/common.c | 7 +++-- include/exec/memory.h | 48 - kvm-all.c | 23 ++-- memory.c | 17 +++- target-i386/kvm.c | 18 + target-mips/kvm.c | 4 +++ target-ppc/kvm.c | 4 +++ translate-all.c | 3 +++ 10 files changed, 177 insertions(+), 23 deletions(-) -- 2.3.0