From 8619b5ddb56f562c751bcdac2328abcbff37fdeb Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 23 Jun 2021 11:11:35 +0200 Subject: ci: build & store windows installer Build windows installer for qemu in gitlab CI, store the result as artifact. Signed-off-by: Gerd Hoffmann Reviewed-by: Willian Rampazzo Reviewed-by: Thomas Huth Message-Id: <20210623091137.1156959-2-kraxel@redhat.com> Signed-off-by: Thomas Huth --- .gitlab-ci.d/crossbuild-template.yml | 5 +++++ .gitlab-ci.d/crossbuilds.yml | 6 ++++++ tests/docker/dockerfiles/fedora-win64-cross.docker | 1 + 3 files changed, 12 insertions(+) diff --git a/.gitlab-ci.d/crossbuild-template.yml b/.gitlab-ci.d/crossbuild-template.yml index 1be5411..7d3ad00 100644 --- a/.gitlab-ci.d/crossbuild-template.yml +++ b/.gitlab-ci.d/crossbuild-template.yml @@ -11,6 +11,11 @@ i386-softmmu microblaze-softmmu mips-softmmu mipsel-softmmu mips64-softmmu ppc-softmmu sh4-softmmu xtensa-softmmu" - make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS + - if grep -q "EXESUF=.exe" config-host.mak; + then make installer; + version="$(git describe --match v[0-9]*)"; + mv -v qemu-setup*.exe qemu-setup-${version}.exe; + fi # Job to cross-build specific accelerators. # diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml index 6b3865c..4ff3aa3 100644 --- a/.gitlab-ci.d/crossbuilds.yml +++ b/.gitlab-ci.d/crossbuilds.yml @@ -160,6 +160,9 @@ cross-win32-system: job: win32-fedora-cross-container variables: IMAGE: fedora-win32-cross + artifacts: + paths: + - build/qemu-setup*.exe cross-win64-system: extends: .cross_system_build_job @@ -167,6 +170,9 @@ cross-win64-system: job: win64-fedora-cross-container variables: IMAGE: fedora-win64-cross + artifacts: + paths: + - build/qemu-setup*.exe cross-amd64-xen-only: extends: .cross_accel_build_job diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker index ff70604..d3f1366 100644 --- a/tests/docker/dockerfiles/fedora-win64-cross.docker +++ b/tests/docker/dockerfiles/fedora-win64-cross.docker @@ -13,6 +13,7 @@ ENV PACKAGES \ hostname \ make \ meson \ + mingw32-nsis \ mingw64-bzip2 \ mingw64-curl \ mingw64-glib2 \ -- cgit v1.1 From 659eb157a55666bf379f5362238a86d855e262e2 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 15 Jul 2021 10:39:28 +0200 Subject: configure: Fix endianess test with LTO If a user is trying to compile QEMU with link-time optimization enabled by running the configure script like this: .../configure --extra-cflags="-flto" then the endianess test is failing since the magic values do not show up in the intermediate object files there. If the host is a big endian machine (like s390x), the QEMU binary is then unusable since the corresponding variable "bigendian" is pre-initialized with "no". To fix this issue, we should rather create a full binary and look for the magic strings there instead. And we really should not continue the build if the endianess check failed, to make it clear right from the start that something went wrong here, thus let's also add some "exit 1" statements here after emitting the error message. Message-Id: <20210715083928.933806-1-thuth@redhat.com> Reviewed-by: Richard Henderson Signed-off-by: Thomas Huth --- configure | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/configure b/configure index 49b5481..63f38fa 100755 --- a/configure +++ b/configure @@ -2365,24 +2365,27 @@ feature_not_found() { # --- # big/little endian test cat > $TMPC << EOF +#include short big_endian[] = { 0x4269, 0x4765, 0x4e64, 0x4961, 0x4e00, 0, }; short little_endian[] = { 0x694c, 0x7454, 0x654c, 0x6e45, 0x6944, 0x6e41, 0, }; -extern int foo(short *, short *); -int main(int argc, char *argv[]) { - return foo(big_endian, little_endian); +int main(int argc, char *argv[]) +{ + return printf("%s %s\n", (char *)big_endian, (char *)little_endian); } EOF -if compile_object ; then - if strings -a $TMPO | grep -q BiGeNdIaN ; then +if compile_prog ; then + if strings -a $TMPE | grep -q BiGeNdIaN ; then bigendian="yes" - elif strings -a $TMPO | grep -q LiTtLeEnDiAn ; then + elif strings -a $TMPE | grep -q LiTtLeEnDiAn ; then bigendian="no" else echo big/little test failed + exit 1 fi else echo big/little test failed + exit 1 fi ########################################## -- cgit v1.1 From 6a932c4ed8748b08c58cdba3fc9485d5549aacca Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 15 Jul 2021 12:37:55 +0200 Subject: hw/net/vmxnet3: Do not abort if the guest is trying to use an invalid TX queue QEMU should never abort just because the guest is doing something odd. Let's simply log the error and ignore the bad transmit queue instead. Buglink: https://bugs.launchpad.net/qemu/+bug/1926111 Message-Id: <20210715103755.1035566-1-thuth@redhat.com> Reviewed-by: Richard Henderson Signed-off-by: Thomas Huth --- hw/net/vmxnet3.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index eff299f..f6bd8c5 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -23,6 +23,7 @@ #include "net/checksum.h" #include "sysemu/sysemu.h" #include "qemu/bswap.h" +#include "qemu/log.h" #include "qemu/module.h" #include "hw/pci/msix.h" #include "hw/pci/msi.h" @@ -1093,8 +1094,12 @@ vmxnet3_io_bar0_write(void *opaque, hwaddr addr, int tx_queue_idx = VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_TXPROD, VMXNET3_REG_ALIGN); - assert(tx_queue_idx <= s->txq_num); - vmxnet3_process_tx_queue(s, tx_queue_idx); + if (tx_queue_idx <= s->txq_num) { + vmxnet3_process_tx_queue(s, tx_queue_idx); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "vmxnet3: Illegal TX queue %d/%d\n", + tx_queue_idx, s->txq_num); + } return; } -- cgit v1.1 From 283f0a05e24a5e5fab78305f783f06215390d620 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 15 Jul 2021 21:32:19 +0200 Subject: hw/net/net_tx_pkt: Fix crash detected by fuzzer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QEMU currently crashes when it's started like this: cat << EOF | ./qemu-system-i386 -device vmxnet3 -nodefaults -qtest stdio outl 0xcf8 0x80001014 outl 0xcfc 0xe0001000 outl 0xcf8 0x80001018 outl 0xcf8 0x80001004 outw 0xcfc 0x7 outl 0xcf8 0x80001083 write 0x0 0x1 0xe1 write 0x1 0x1 0xfe write 0x2 0x1 0xbe write 0x3 0x1 0xba writeq 0xe0001020 0xefefff5ecafe0000 writeq 0xe0001020 0xffff5e5ccafe0002 EOF It hits this assertion: qemu-system-i386: ../qemu/hw/net/net_tx_pkt.c:453: net_tx_pkt_reset: Assertion `pkt->raw' failed. This happens because net_tx_pkt_init() is called with max_frags == 0 and thus the allocation p->raw = g_new(struct iovec, max_frags); results in a NULL pointer that causes the assert(pkt->raw); in net_tx_pkt_reset() to fail later. To fix this issue we can check that max_raw_frags was not zero before asserting that pkt->raw is a non-NULL pointer. Buglink: https://bugs.launchpad.net/qemu/+bug/1890157 Message-Id: <20210715193219.1132571-1-thuth@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Pankaj Gupta Signed-off-by: Thomas Huth --- hw/net/net_tx_pkt.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c index 1f9aa59..1cb1125 100644 --- a/hw/net/net_tx_pkt.c +++ b/hw/net/net_tx_pkt.c @@ -450,11 +450,13 @@ void net_tx_pkt_reset(struct NetTxPkt *pkt) pkt->payload_len = 0; pkt->payload_frags = 0; - assert(pkt->raw); - for (i = 0; i < pkt->raw_frags; i++) { - assert(pkt->raw[i].iov_base); - pci_dma_unmap(pkt->pci_dev, pkt->raw[i].iov_base, pkt->raw[i].iov_len, - DMA_DIRECTION_TO_DEVICE, 0); + if (pkt->max_raw_frags > 0) { + assert(pkt->raw); + for (i = 0; i < pkt->raw_frags; i++) { + assert(pkt->raw[i].iov_base); + pci_dma_unmap(pkt->pci_dev, pkt->raw[i].iov_base, + pkt->raw[i].iov_len, DMA_DIRECTION_TO_DEVICE, 0); + } } pkt->raw_frags = 0; -- cgit v1.1 From 9405d87be25db6dff4d7b5ab48a81bbf6d083e47 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 16 Apr 2021 14:52:56 +0200 Subject: hw/ide: Fix crash when plugging a piix3-ide device into the x-remote machine QEMU currently crashes when the user tries to do something like: qemu-system-x86_64 -M x-remote -device piix3-ide This happens because the "isabus" variable is not initialized with the x-remote machine yet. Add a proper check for this condition and propagate the error to the caller, so we can fail there gracefully. Message-Id: <20210416125256.2039734-1-thuth@redhat.com> Reviewed-by: John Snow Signed-off-by: Thomas Huth --- hw/ide/ioport.c | 16 ++++++++++------ hw/ide/piix.c | 22 +++++++++++++++++----- hw/isa/isa-bus.c | 14 ++++++++++---- include/hw/ide/internal.h | 2 +- include/hw/isa/isa.h | 13 ++++++++----- 5 files changed, 46 insertions(+), 21 deletions(-) diff --git a/hw/ide/ioport.c b/hw/ide/ioport.c index b613ff3..e6caa53 100644 --- a/hw/ide/ioport.c +++ b/hw/ide/ioport.c @@ -50,15 +50,19 @@ static const MemoryRegionPortio ide_portio2_list[] = { PORTIO_END_OF_LIST(), }; -void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2) +int ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2) { + int ret; + /* ??? Assume only ISA and PCI configurations, and that the PCI-ISA bridge has been setup properly to always register with ISA. */ - isa_register_portio_list(dev, &bus->portio_list, - iobase, ide_portio_list, bus, "ide"); + ret = isa_register_portio_list(dev, &bus->portio_list, + iobase, ide_portio_list, bus, "ide"); - if (iobase2) { - isa_register_portio_list(dev, &bus->portio2_list, - iobase2, ide_portio2_list, bus, "ide"); + if (ret == 0 && iobase2) { + ret = isa_register_portio_list(dev, &bus->portio2_list, + iobase2, ide_portio2_list, bus, "ide"); } + + return ret; } diff --git a/hw/ide/piix.c b/hw/ide/piix.c index b9860e3..d3e7383 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "hw/pci/pci.h" #include "migration/vmstate.h" +#include "qapi/error.h" #include "qemu/module.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" @@ -123,7 +124,8 @@ static void piix_ide_reset(DeviceState *dev) pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */ } -static void pci_piix_init_ports(PCIIDEState *d) { +static int pci_piix_init_ports(PCIIDEState *d) +{ static const struct { int iobase; int iobase2; @@ -132,24 +134,30 @@ static void pci_piix_init_ports(PCIIDEState *d) { {0x1f0, 0x3f6, 14}, {0x170, 0x376, 15}, }; - int i; + int i, ret; for (i = 0; i < 2; i++) { ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2); - ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase, - port_info[i].iobase2); + ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase, + port_info[i].iobase2); + if (ret) { + return ret; + } ide_init2(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq)); bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; ide_register_restart_cb(&d->bus[i]); } + + return 0; } static void pci_piix_ide_realize(PCIDevice *dev, Error **errp) { PCIIDEState *d = PCI_IDE(dev); uint8_t *pci_conf = dev->config; + int rc; pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode @@ -158,7 +166,11 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp) vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_pci, d); - pci_piix_init_ports(d); + rc = pci_piix_init_ports(d); + if (rc) { + error_setg_errno(errp, -rc, "Failed to realize %s", + object_get_typename(OBJECT(dev))); + } } int pci_piix3_xen_ide_unplug(DeviceState *dev, bool aux) diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c index 7820068..cffaa35 100644 --- a/hw/isa/isa-bus.c +++ b/hw/isa/isa-bus.c @@ -131,13 +131,17 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start) isa_init_ioport(dev, start); } -void isa_register_portio_list(ISADevice *dev, - PortioList *piolist, uint16_t start, - const MemoryRegionPortio *pio_start, - void *opaque, const char *name) +int isa_register_portio_list(ISADevice *dev, + PortioList *piolist, uint16_t start, + const MemoryRegionPortio *pio_start, + void *opaque, const char *name) { assert(piolist && !piolist->owner); + if (!isabus) { + return -ENODEV; + } + /* START is how we should treat DEV, regardless of the actual contents of the portio array. This is how the old code actually handled e.g. the FDC device. */ @@ -145,6 +149,8 @@ void isa_register_portio_list(ISADevice *dev, portio_list_init(piolist, OBJECT(dev), pio_start, opaque, name); portio_list_add(piolist, isabus->address_space_io, start); + + return 0; } static void isa_device_init(Object *obj) diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h index 2d09162..7917221 100644 --- a/include/hw/ide/internal.h +++ b/include/hw/ide/internal.h @@ -624,7 +624,7 @@ int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind, int chs_trans, Error **errp); void ide_init2(IDEBus *bus, qemu_irq irq); void ide_exit(IDEState *s); -void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2); +int ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2); void ide_register_restart_cb(IDEBus *bus); void ide_exec_cmd(IDEBus *bus, uint32_t val); diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index ddaae89..d4417b3 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -132,12 +132,15 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start); * @portio: the ports, sorted by offset. * @opaque: passed into the portio callbacks. * @name: passed into memory_region_init_io. + * + * Returns: 0 on success, negative error code otherwise (e.g. if the + * ISA bus is not available) */ -void isa_register_portio_list(ISADevice *dev, - PortioList *piolist, - uint16_t start, - const MemoryRegionPortio *portio, - void *opaque, const char *name); +int isa_register_portio_list(ISADevice *dev, + PortioList *piolist, + uint16_t start, + const MemoryRegionPortio *portio, + void *opaque, const char *name); static inline ISABus *isa_bus_from_device(ISADevice *d) { -- cgit v1.1