From 6a23f8190fe953546ce50142d037588fb972f8ce Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 16 Nov 2021 08:28:29 +0100 Subject: [PATCH 01/79] meson: fix botched compile check conversions Fix a bunch of incorrect conversions from configure to Meson, which result in different outcomes with --extra-cflags=-Werror. pthread_setname_np needs "#define _GNU_SOURCE" on Linux (which I am using also for the non-Linux check, so that it correctly fails with an error about having too few parameters). Fix struct checks to use has_type instead of has_symbol, and "#define _GNU_SOURCE" too in the case of struct mmsghdr. Remove an apostrophe that ended up at the end of a #include line. Reported-by: Peter Maydell Signed-off-by: Paolo Bonzini --- meson.build | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/meson.build b/meson.build index 2ece4fe088..93a5e50a16 100644 --- a/meson.build +++ b/meson.build @@ -1547,8 +1547,6 @@ config_host_data.set('CONFIG_INOTIFY', cc.has_header_symbol('sys/inotify.h', 'inotify_init')) config_host_data.set('CONFIG_INOTIFY1', cc.has_header_symbol('sys/inotify.h', 'inotify_init1')) -config_host_data.set('CONFIG_IOVEC', - cc.has_header_symbol('sys/uio.h', 'struct iovec')) config_host_data.set('CONFIG_MACHINE_BSWAP_H', cc.has_header_symbol('machine/bswap.h', 'bswap32', prefix: '''#include @@ -1561,8 +1559,6 @@ config_host_data.set('CONFIG_SYSMACROS', cc.has_header_symbol('sys/sysmacros.h', 'makedev')) config_host_data.set('HAVE_OPTRESET', cc.has_header_symbol('getopt.h', 'optreset')) -config_host_data.set('HAVE_UTMPX', - cc.has_header_symbol('utmpx.h', 'struct utmpx')) config_host_data.set('HAVE_IPPROTO_MPTCP', cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) @@ -1574,6 +1570,14 @@ config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM', cc.has_member('struct stat', 'st_atim', prefix: '#include ')) +# has_type +config_host_data.set('CONFIG_IOVEC', + cc.has_type('struct iovec', + prefix: '#include ')) +config_host_data.set('HAVE_UTMPX', + cc.has_type('struct utmpx', + prefix: '#include ')) + config_host_data.set('CONFIG_EVENTFD', cc.links(''' #include int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }''')) @@ -1615,7 +1619,7 @@ config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + ''' #include int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }''')) -config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(''' +config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + ''' #include static void *f(void *p) { return NULL; } @@ -1626,7 +1630,7 @@ config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(''' pthread_setname_np(thread, "QEMU"); return 0; }''', dependencies: threads)) -config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(''' +config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + ''' #include static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; } @@ -1662,8 +1666,10 @@ config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + ''' have_l2tpv3 = false if not get_option('l2tpv3').disabled() and have_system - have_l2tpv3 = (cc.has_header_symbol('sys/socket.h', 'struct mmsghdr') - and cc.has_header('linux/ip.h')) + have_l2tpv3 = cc.has_type('struct mmsghdr', + prefix: gnu_source_prefix + ''' + #include + #include ''') endif config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) @@ -1689,7 +1695,7 @@ config_host_data.set('CONFIG_NETMAP', have_netmap) # xfs headers will not try to redefine structs from linux headers # if this macro is set. config_host_data.set('HAVE_FSXATTR', cc.links(''' - #include ' + #include struct fsxattr foo; int main(void) { return 0; From 14554b3dccae18ddc58d39654443c8e4551252c9 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Tue, 16 Nov 2021 16:08:37 +0100 Subject: [PATCH 02/79] pmu: fix pmu vmstate subsection list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The subsection is not closed by a NULL marker so this can trigger a segfault when the pmu vmstate is saved. This can be easily shown with: $ ./qemu-system-ppc64 -dump-vmstate vmstate.json Segmentation fault (core dumped) Fixes: d811d61fbc6c ("mac_newworld: add PMU device") Cc: mark.cave-ayland@ilande.co.uk Signed-off-by: Laurent Vivier Reviewed-by: Greg Kurz Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Mark Cave-Ayland Signed-off-by: Cédric Le Goater --- hw/misc/macio/pmu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c index 4ad4f50e08..eb39c64694 100644 --- a/hw/misc/macio/pmu.c +++ b/hw/misc/macio/pmu.c @@ -718,6 +718,7 @@ static const VMStateDescription vmstate_pmu = { }, .subsections = (const VMStateDescription * []) { &vmstate_pmu_adb, + NULL } }; From a443d55c3f7cafa3d5dfb7fe2b5c3cd9d671b61d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 17 Nov 2021 18:33:53 +0100 Subject: [PATCH 03/79] tests/tcg/ppc64le: Fix compile flags for byte_reverse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With a host compiler new enough to recognize power10 insns, CROSS_CC_HAS_POWER10 is true, but we do not supply the -cpu option to the compiler, resulting in /tmp/ccAVdYJd.s: Assembler messages: /tmp/ccAVdYJd.s:49: Error: unrecognized opcode: `brh' /tmp/ccAVdYJd.s:78: Error: unrecognized opcode: `brw' /tmp/ccAVdYJd.s:107: Error: unrecognized opcode: `brd' make[2]: *** [byte_reverse] Error 1 Signed-off-by: Richard Henderson Signed-off-by: Cédric Le Goater --- tests/tcg/ppc64le/Makefile.target | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/tcg/ppc64le/Makefile.target b/tests/tcg/ppc64le/Makefile.target index 5e65b1590d..ba2fde5ff1 100644 --- a/tests/tcg/ppc64le/Makefile.target +++ b/tests/tcg/ppc64le/Makefile.target @@ -9,18 +9,12 @@ PPC64LE_TESTS=bcdsub endif bcdsub: CFLAGS += -mpower8-vector -PPC64LE_TESTS += byte_reverse ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER10),) +PPC64LE_TESTS += byte_reverse +endif +byte_reverse: CFLAGS += -mcpu=power10 run-byte_reverse: QEMU_OPTS+=-cpu POWER10 run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10 -else -byte_reverse: - $(call skip-test, "BUILD of $@", "missing compiler support") -run-byte_reverse: - $(call skip-test, "RUN of byte_reverse", "not built") -run-plugin-byte_reverse-with-%: - $(call skip-test, "RUN of byte_reverse ($*)", "not built") -endif PPC64LE_TESTS += signal_save_restore_xer From 0cc4965049d9792ffede8fc371b58193d6ecbb02 Mon Sep 17 00:00:00 2001 From: nia Date: Wed, 13 Oct 2021 13:54:17 +0000 Subject: [PATCH 04/79] nvmm: Fix support for stable version NVMM user version 1 is the version being shipped with netbsd-9, which is the most recent stable branch of NetBSD. This makes it possible to use the NVMM accelerator on the most recent NetBSD release, 9.2, which lacks nvmm_cpu_stop. (CC'ing maintainers) Signed-off-by: Nia Alarie Reviewed-by: Kamil Rytarowski Message-Id: Signed-off-by: Paolo Bonzini --- meson.build | 4 +--- target/i386/nvmm/nvmm-all.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index 93a5e50a16..582f356209 100644 --- a/meson.build +++ b/meson.build @@ -323,9 +323,7 @@ if not get_option('hax').disabled() endif endif if targetos == 'netbsd' - if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm')) - nvmm = cc.find_library('nvmm', required: get_option('nvmm')) - endif + nvmm = cc.find_library('nvmm', required: get_option('nvmm')) if nvmm.found() accelerators += 'CONFIG_NVMM' endif diff --git a/target/i386/nvmm/nvmm-all.c b/target/i386/nvmm/nvmm-all.c index 14c996f968..9af261eea3 100644 --- a/target/i386/nvmm/nvmm-all.c +++ b/target/i386/nvmm/nvmm-all.c @@ -750,7 +750,11 @@ nvmm_vcpu_loop(CPUState *cpu) nvmm_vcpu_pre_run(cpu); if (qatomic_read(&cpu->exit_request)) { +#if NVMM_USER_VERSION >= 2 nvmm_vcpu_stop(vcpu); +#else + qemu_cpu_kick_self(); +#endif } /* Read exit_request before the kernel reads the immediate exit flag */ @@ -767,6 +771,7 @@ nvmm_vcpu_loop(CPUState *cpu) switch (exit->reason) { case NVMM_VCPU_EXIT_NONE: break; +#if NVMM_USER_VERSION >= 2 case NVMM_VCPU_EXIT_STOPPED: /* * The kernel cleared the immediate exit flag; cpu->exit_request @@ -775,6 +780,7 @@ nvmm_vcpu_loop(CPUState *cpu) smp_wmb(); qcpu->stop = true; break; +#endif case NVMM_VCPU_EXIT_MEMORY: ret = nvmm_handle_mem(mach, vcpu); break; @@ -888,8 +894,12 @@ nvmm_ipi_signal(int sigcpu) { if (current_cpu) { struct qemu_vcpu *qcpu = get_qemu_vcpu(current_cpu); +#if NVMM_USER_VERSION >= 2 struct nvmm_vcpu *vcpu = &qcpu->vcpu; nvmm_vcpu_stop(vcpu); +#else + qcpu->stop = true; +#endif } } From 3f26c9757726918015d351fafc436b2888689985 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 18 Nov 2021 10:03:26 +0000 Subject: [PATCH 05/79] esp: ensure that async_len is reset to 0 during esp_hard_reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a reset command is sent after data has been transferred into the SCSI buffer ensure that async_len is reset to 0. Otherwise a subsequent TI command assumes the SCSI buffer contains data to be transferred to the device causing it to dereference the stale async_buf pointer. Signed-off-by: Mark Cave-Ayland Fixes: https://gitlab.com/qemu-project/qemu/-/issues/724 Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211118100327.29061-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini --- hw/scsi/esp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index 84f935b549..58d0edbd56 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -894,6 +894,7 @@ void esp_hard_reset(ESPState *s) memset(s->wregs, 0, ESP_REGS); s->tchi_written = 0; s->ti_size = 0; + s->async_len = 0; fifo8_reset(&s->fifo); fifo8_reset(&s->cmdfifo); s->dma = 0; From 283191640c875e0b3e79c75ba2c6bc6b96588666 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 18 Nov 2021 10:03:27 +0000 Subject: [PATCH 06/79] qtest/am53c974-test: add test for reset before transfer Based upon the qtest reproducer posted to Gitlab issue #724 at https://gitlab.com/qemu-project/qemu/-/issues/724. Signed-off-by: Mark Cave-Ayland Acked-by: Thomas Huth Message-Id: <20211118100327.29061-3-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini --- tests/qtest/am53c974-test.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/qtest/am53c974-test.c b/tests/qtest/am53c974-test.c index 9b1e4211bd..d214a912b3 100644 --- a/tests/qtest/am53c974-test.c +++ b/tests/qtest/am53c974-test.c @@ -223,6 +223,34 @@ static void test_inflight_cancel_ok(void) qtest_quit(s); } +static void test_reset_before_transfer_ok(void) +{ + QTestState *s = qtest_init( + "-device am53c974,id=scsi " + "-device scsi-hd,drive=disk0 -drive " + "id=disk0,if=none,file=null-co://,format=raw -nodefaults"); + + qtest_outl(s, 0xcf8, 0x80001010); + qtest_outl(s, 0xcfc, 0xc000); + qtest_outl(s, 0xcf8, 0x80001004); + qtest_outw(s, 0xcfc, 0x01); + qtest_outl(s, 0xc007, 0x2500); + qtest_outl(s, 0xc00a, 0x410000); + qtest_outl(s, 0xc00a, 0x410000); + qtest_outw(s, 0xc00b, 0x0200); + qtest_outw(s, 0xc040, 0x03); + qtest_outw(s, 0xc009, 0x00); + qtest_outw(s, 0xc00b, 0x00); + qtest_outw(s, 0xc009, 0x00); + qtest_outw(s, 0xc00b, 0x00); + qtest_outw(s, 0xc009, 0x00); + qtest_outw(s, 0xc003, 0x1000); + qtest_outw(s, 0xc00b, 0x1000); + qtest_outl(s, 0xc00b, 0x9000); + qtest_outw(s, 0xc00b, 0x1000); + qtest_quit(s); +} + int main(int argc, char **argv) { const char *arch = qtest_get_arch(); @@ -248,6 +276,8 @@ int main(int argc, char **argv) test_cancelled_request_ok); qtest_add_func("am53c974/test_inflight_cancel_ok", test_inflight_cancel_ok); + qtest_add_func("am53c974/test_reset_before_transfer_ok", + test_reset_before_transfer_ok); } return g_test_run(); From 5135fe71101db08cf65090963247f9b1b8138b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 18 Nov 2021 15:34:01 +0100 Subject: [PATCH 07/79] docs: Spell QEMU all caps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace Qemu -> QEMU. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Darren Kenny Reviewed-by: Markus Armbruster Message-Id: <20211118143401.4101497-1-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- docs/devel/modules.rst | 2 +- docs/devel/multi-thread-tcg.rst | 2 +- docs/devel/style.rst | 2 +- docs/devel/ui.rst | 4 ++-- docs/interop/nbd.txt | 6 +++--- docs/interop/qcow2.txt | 8 ++++---- docs/multiseat.txt | 2 +- docs/system/device-url-syntax.rst.inc | 2 +- docs/system/i386/sgx.rst | 26 +++++++++++++------------- docs/u2f.txt | 2 +- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/devel/modules.rst b/docs/devel/modules.rst index 066f347b89..8e999c4fa4 100644 --- a/docs/devel/modules.rst +++ b/docs/devel/modules.rst @@ -1,5 +1,5 @@ ============ -Qemu modules +QEMU modules ============ .. kernel-doc:: include/qemu/module.h diff --git a/docs/devel/multi-thread-tcg.rst b/docs/devel/multi-thread-tcg.rst index 5b446ee08b..c9541a7b20 100644 --- a/docs/devel/multi-thread-tcg.rst +++ b/docs/devel/multi-thread-tcg.rst @@ -228,7 +228,7 @@ Emulated hardware state Currently thanks to KVM work any access to IO memory is automatically protected by the global iothread mutex, also known as the BQL (Big -Qemu Lock). Any IO region that doesn't use global mutex is expected to +QEMU Lock). Any IO region that doesn't use global mutex is expected to do its own locking. However IO memory isn't the only way emulated hardware state can be diff --git a/docs/devel/style.rst b/docs/devel/style.rst index 260e3263fa..e00af62e76 100644 --- a/docs/devel/style.rst +++ b/docs/devel/style.rst @@ -686,7 +686,7 @@ Rationale: hex numbers are hard to read in logs when there is no 0x prefix, especially when (occasionally) the representation doesn't contain any letters and especially in one line with other decimal numbers. Number groups are allowed to not use '0x' because for some things notations like %x.%x.%x are used not -only in Qemu. Also dumping raw data bytes with '0x' is less readable. +only in QEMU. Also dumping raw data bytes with '0x' is less readable. '#' printf flag --------------- diff --git a/docs/devel/ui.rst b/docs/devel/ui.rst index 06c7d622ce..17fb667dec 100644 --- a/docs/devel/ui.rst +++ b/docs/devel/ui.rst @@ -1,8 +1,8 @@ ================= -Qemu UI subsystem +QEMU UI subsystem ================= -Qemu Clipboard +QEMU Clipboard -------------- .. kernel-doc:: include/ui/clipboard.h diff --git a/docs/interop/nbd.txt b/docs/interop/nbd.txt index 10ce098a29..bdb0f2a41a 100644 --- a/docs/interop/nbd.txt +++ b/docs/interop/nbd.txt @@ -1,4 +1,4 @@ -Qemu supports the NBD protocol, and has an internal NBD client (see +QEMU supports the NBD protocol, and has an internal NBD client (see block/nbd.c), an internal NBD server (see blockdev-nbd.c), and an external NBD server tool (see qemu-nbd.c). The common code is placed in nbd/*. @@ -7,11 +7,11 @@ The NBD protocol is specified here: https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md The following paragraphs describe some specific properties of NBD -protocol realization in Qemu. +protocol realization in QEMU. = Metadata namespaces = -Qemu supports the "base:allocation" metadata context as defined in the +QEMU supports the "base:allocation" metadata context as defined in the NBD protocol specification, and also defines an additional metadata namespace "qemu". diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt index 0463f761ef..f7dc304ff6 100644 --- a/docs/interop/qcow2.txt +++ b/docs/interop/qcow2.txt @@ -313,7 +313,7 @@ The fields of the bitmaps extension are: The number of bitmaps contained in the image. Must be greater than or equal to 1. - Note: Qemu currently only supports up to 65535 bitmaps per + Note: QEMU currently only supports up to 65535 bitmaps per image. 4 - 7: Reserved, must be zero. @@ -775,7 +775,7 @@ Structure of a bitmap directory entry: 2: extra_data_compatible This flags is meaningful when the extra data is unknown to the software (currently any extra data is - unknown to Qemu). + unknown to QEMU). If it is set, the bitmap may be used as expected, extra data must be left as is. If it is not set, the bitmap must not be used, but @@ -793,7 +793,7 @@ Structure of a bitmap directory entry: 17: granularity_bits Granularity bits. Valid values: 0 - 63. - Note: Qemu currently supports only values 9 - 31. + Note: QEMU currently supports only values 9 - 31. Granularity is calculated as granularity = 1 << granularity_bits @@ -804,7 +804,7 @@ Structure of a bitmap directory entry: 18 - 19: name_size Size of the bitmap name. Must be non-zero. - Note: Qemu currently doesn't support values greater than + Note: QEMU currently doesn't support values greater than 1023. 20 - 23: extra_data_size diff --git a/docs/multiseat.txt b/docs/multiseat.txt index 11850c96ff..2b297e979d 100644 --- a/docs/multiseat.txt +++ b/docs/multiseat.txt @@ -123,7 +123,7 @@ Background info is here: guest side with pci-bridge-seat ------------------------------- -Qemu version 2.4 and newer has a new pci-bridge-seat device which +QEMU version 2.4 and newer has a new pci-bridge-seat device which can be used instead of pci-bridge. Just swap the device name in the qemu command line above. The only difference between the two devices is the pci id. We can match the pci id instead of the device path diff --git a/docs/system/device-url-syntax.rst.inc b/docs/system/device-url-syntax.rst.inc index d15a021508..7dbc525fa8 100644 --- a/docs/system/device-url-syntax.rst.inc +++ b/docs/system/device-url-syntax.rst.inc @@ -15,7 +15,7 @@ These are specified using a special URL syntax. 'iqn.2008-11.org.linux-kvm[:]' but this can also be set from the command line or a configuration file. - Since version Qemu 2.4 it is possible to specify a iSCSI request + Since version QEMU 2.4 it is possible to specify a iSCSI request timeout to detect stalled requests and force a reestablishment of the session. The timeout is specified in seconds. The default is 0 which means no timeout. Libiscsi 1.15.0 or greater is required for this diff --git a/docs/system/i386/sgx.rst b/docs/system/i386/sgx.rst index 9aa161af1a..f8fade5ac2 100644 --- a/docs/system/i386/sgx.rst +++ b/docs/system/i386/sgx.rst @@ -20,13 +20,13 @@ report the same CPUID info to guest as on host for most of SGX CPUID. With reporting the same CPUID guest is able to use full capacity of SGX, and KVM doesn't need to emulate those info. -The guest's EPC base and size are determined by Qemu, and KVM needs Qemu to +The guest's EPC base and size are determined by QEMU, and KVM needs QEMU to notify such info to it before it can initialize SGX for guest. Virtual EPC ~~~~~~~~~~~ -By default, Qemu does not assign EPC to a VM, i.e. fully enabling SGX in a VM +By default, QEMU does not assign EPC to a VM, i.e. fully enabling SGX in a VM requires explicit allocation of EPC to the VM. Similar to other specialized memory types, e.g. hugetlbfs, EPC is exposed as a memory backend. @@ -35,12 +35,12 @@ prior to realizing the vCPUs themselves, which occurs long before generic devices are parsed and realized. This limitation means that EPC does not require -maxmem as EPC is not treated as {cold,hot}plugged memory. -Qemu does not artificially restrict the number of EPC sections exposed to a -guest, e.g. Qemu will happily allow you to create 64 1M EPC sections. Be aware +QEMU does not artificially restrict the number of EPC sections exposed to a +guest, e.g. QEMU will happily allow you to create 64 1M EPC sections. Be aware that some kernels may not recognize all EPC sections, e.g. the Linux SGX driver is hardwired to support only 8 EPC sections. -The following Qemu snippet creates two EPC sections, with 64M pre-allocated +The following QEMU snippet creates two EPC sections, with 64M pre-allocated to the VM and an additional 28M mapped but not allocated:: -object memory-backend-epc,id=mem1,size=64M,prealloc=on \ @@ -54,7 +54,7 @@ to physical EPC. Because physical EPC is protected via range registers, the size of the physical EPC must be a power of two (though software sees a subset of the full EPC, e.g. 92M or 128M) and the EPC must be naturally aligned. KVM SGX's virtual EPC is purely a software construct and only -requires the size and location to be page aligned. Qemu enforces the EPC +requires the size and location to be page aligned. QEMU enforces the EPC size is a multiple of 4k and will ensure the base of the EPC is 4k aligned. To simplify the implementation, EPC is always located above 4g in the guest physical address space. @@ -62,7 +62,7 @@ physical address space. Migration ~~~~~~~~~ -Qemu/KVM doesn't prevent live migrating SGX VMs, although from hardware's +QEMU/KVM doesn't prevent live migrating SGX VMs, although from hardware's perspective, SGX doesn't support live migration, since both EPC and the SGX key hierarchy are bound to the physical platform. However live migration can be supported in the sense if guest software stack can support recreating @@ -76,7 +76,7 @@ CPUID ~~~~~ Due to its myriad dependencies, SGX is currently not listed as supported -in any of Qemu's built-in CPU configuration. To expose SGX (and SGX Launch +in any of QEMU's built-in CPU configuration. To expose SGX (and SGX Launch Control) to a guest, you must either use ``-cpu host`` to pass-through the host CPU model, or explicitly enable SGX when using a built-in CPU model, e.g. via ``-cpu ,+sgx`` or ``-cpu ,+sgx,+sgxlc``. @@ -101,7 +101,7 @@ controlled via -cpu are prefixed with "sgx", e.g.:: sgx2 sgxlc -The following Qemu snippet passes through the host CPU but restricts access to +The following QEMU snippet passes through the host CPU but restricts access to the provision and EINIT token keys:: -cpu host,-sgx-provisionkey,-sgx-tokenkey @@ -112,11 +112,11 @@ in hardware cannot be forced on via '-cpu'. Virtualize SGX Launch Control ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Qemu SGX support for Launch Control (LC) is passive, in the sense that it -does not actively change the LC configuration. Qemu SGX provides the user +QEMU SGX support for Launch Control (LC) is passive, in the sense that it +does not actively change the LC configuration. QEMU SGX provides the user the ability to set/clear the CPUID flag (and by extension the associated IA32_FEATURE_CONTROL MSR bit in fw_cfg) and saves/restores the LE Hash MSRs -when getting/putting guest state, but Qemu does not add new controls to +when getting/putting guest state, but QEMU does not add new controls to directly modify the LC configuration. Similar to hardware behavior, locking the LC configuration to a non-Intel value is left to guest firmware. Unlike host bios setting for SGX launch control(LC), there is no special bios setting @@ -126,7 +126,7 @@ creating VM with SGX. Feature Control ~~~~~~~~~~~~~~~ -Qemu SGX updates the ``etc/msr_feature_control`` fw_cfg entry to set the SGX +QEMU SGX updates the ``etc/msr_feature_control`` fw_cfg entry to set the SGX (bit 18) and SGX LC (bit 17) flags based on their respective CPUID support, i.e. existing guest firmware will automatically set SGX and SGX LC accordingly, assuming said firmware supports fw_cfg.msr_feature_control. diff --git a/docs/u2f.txt b/docs/u2f.txt index 8f44994818..7f5813a0b7 100644 --- a/docs/u2f.txt +++ b/docs/u2f.txt @@ -21,7 +21,7 @@ The second factor is materialized by a device implementing the U2F protocol. In case of a USB U2F security key, it is a USB HID device that implements the U2F protocol. -In Qemu, the USB U2F key device offers a dedicated support of U2F, allowing +In QEMU, the USB U2F key device offers a dedicated support of U2F, allowing guest USB FIDO/U2F security keys operating in two possible modes: pass-through and emulated. From fbab8cc24ded54f371ab9db2c9998be23c158e62 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Wed, 17 Nov 2021 21:53:55 +0100 Subject: [PATCH 08/79] meson.build: Support ncurses on MacOS and OpenBSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MacOS provides header files for curses 5.7 with support for wide characters, but requires _XOPEN_SOURCE_EXTENDED=1 to activate that. By default those old header files are used even if there is a newer Homebrew installation of ncurses 6.2 available. Change also the old macro definition of NCURSES_WIDECHAR and set it to 1 like it is done in newer versions of curses.h when _XOPEN_SOURCE_EXTENDED=1 is defined. OpenBSD has the same version of ncurses and needs the same fix. Suggested-by: Daniel P. Berrangé Signed-off-by: Stefan Weil Reviewed-by: Daniel P. Berrangé Tested-by: Brad Smith Message-Id: <20211117205355.1392292-1-sw@weilnetz.de> Signed-off-by: Paolo Bonzini --- meson.build | 5 ++++- ui/curses.c | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 582f356209..fbdd415376 100644 --- a/meson.build +++ b/meson.build @@ -679,6 +679,9 @@ iconv = not_found curses = not_found if have_system and not get_option('curses').disabled() curses_test = ''' + #if defined(__APPLE__) || defined(__OpenBSD__) + #define _XOPEN_SOURCE_EXTENDED 1 + #endif #include #include #include @@ -702,7 +705,7 @@ if have_system and not get_option('curses').disabled() endif endforeach msg = get_option('curses').enabled() ? 'curses library not found' : '' - curses_compile_args = ['-DNCURSES_WIDECHAR'] + curses_compile_args = ['-DNCURSES_WIDECHAR=1'] if curses.found() if cc.links(curses_test, args: curses_compile_args, dependencies: [curses]) curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses]) diff --git a/ui/curses.c b/ui/curses.c index e4f9588c3e..861d63244c 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -38,6 +38,10 @@ #include "ui/input.h" #include "sysemu/sysemu.h" +#if defined(__APPLE__) || defined(__OpenBSD__) +#define _XOPEN_SOURCE_EXTENDED 1 +#endif + /* KEY_EVENT is defined in wincon.h and in curses.h. Avoid redefinition. */ #undef KEY_EVENT #include From fdc6e168181d06391711171b7c409b34f2981ced Mon Sep 17 00:00:00 2001 From: Daniil Tatianin Date: Wed, 17 Nov 2021 17:23:49 +0300 Subject: [PATCH 09/79] chardev/wctable: don't free the instance in wctablet_chr_finalize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Object is supposed to be freed by invoking obj->free, and not obj->instance_finalize. This would lead to use-after-free followed by double free in object_unref/object_finalize. Signed-off-by: Daniil Tatianin Reviewed-by: Marc-André Lureau Message-Id: <20211117142349.836279-1-d-tatianin@yandex-team.ru> Signed-off-by: Paolo Bonzini --- chardev/wctablet.c | 1 - 1 file changed, 1 deletion(-) diff --git a/chardev/wctablet.c b/chardev/wctablet.c index 95e005f5a5..e8b292c43c 100644 --- a/chardev/wctablet.c +++ b/chardev/wctablet.c @@ -320,7 +320,6 @@ static void wctablet_chr_finalize(Object *obj) TabletChardev *tablet = WCTABLET_CHARDEV(obj); qemu_input_handler_unregister(tablet->hs); - g_free(tablet); } static void wctablet_chr_open(Chardev *chr, From c29cd47e82df0bc7385cdd49a158d838314daa9e Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 18 Nov 2021 18:18:34 +0000 Subject: [PATCH 10/79] escc: always set STATUS_TXEMPTY in R_STATUS on device reset The "Transmit Interrupts and Transmit Buffer Empty Bit" section of the ESCC datasheet states the following about the STATUS_TXEMPTY bit: "After a hardware reset (including a hardware reset by software), or a channel reset, this bit is set to 1". Update escc_reset() to set the STATUS_TXEMPTY bit in the R_STATUS register on device reset as described which fixes a regression whereby the Sun PROM checks this bit early on startup and gets stuck in an infinite loop if it is not set. Signed-off-by: Mark Cave-Ayland Message-Id: <20211118181835.18497-2-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- hw/char/escc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/char/escc.c b/hw/char/escc.c index 0fce4f6324..a7d9050c83 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -354,6 +354,17 @@ static void escc_reset(DeviceState *d) cs->rregs[j] = 0; cs->wregs[j] = 0; } + + /* + * ...but there is an exception. The "Transmit Interrupts and Transmit + * Buffer Empty Bit" section on page 50 of the ESCC datasheet says of + * the STATUS_TXEMPTY bit in R_STATUS: "After a hardware reset + * (including a hardware reset by software), or a channel reset, this + * bit is set to 1". The Sun PROM checks this bit early on startup and + * gets stuck in an infinite loop if it is not set. + */ + cs->rregs[R_STATUS] |= STATUS_TXEMPTY; + escc_reset_chn(cs); } } From 319e89cdc32096432b578152a47d0d156033b711 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Thu, 18 Nov 2021 18:18:35 +0000 Subject: [PATCH 11/79] escc: update the R_SPEC register SPEC_ALLSENT bit when writing to W_TXCTRL1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ESCC datasheet states that SPEC_ALLSENT is always set in sync mode and set in async mode once all characters have cleared the transmitter. Since writes to SERIAL_DATA use a synchronous chardev API, the guest can never see the state when transmission is in progress so it is possible to set SPEC_ALLSENT in the R_SPEC register unconditionally. This fixes a hang when using the Sun PROM as it attempts to enumerate the onboard serial devices, and a similar hang in OpenBSD SPARC32 where in both cases the boot process will not proceed until SPEC_ALLSENT has been set after writing to W_TXCTRL1. Signed-off-by: Mark Cave-Ayland Message-Id: <20211118181835.18497-3-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé --- hw/char/escc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hw/char/escc.c b/hw/char/escc.c index a7d9050c83..8755d8d34f 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -586,6 +586,20 @@ static void escc_mem_write(void *opaque, hwaddr addr, s->wregs[s->reg] = val; break; case W_TXCTRL1: + s->wregs[s->reg] = val; + /* + * The ESCC datasheet states that SPEC_ALLSENT is always set in + * sync mode, and set in async mode when all characters have + * cleared the transmitter. Since writes to SERIAL_DATA use the + * blocking qemu_chr_fe_write_all() function to write each + * character, the guest can never see the state when async data + * is in the process of being transmitted so we can set this bit + * unconditionally regardless of the state of the W_TXCTRL1 mode + * bits. + */ + s->rregs[R_SPEC] |= SPEC_ALLSENT; + escc_update_parameters(s); + break; case W_TXCTRL2: s->wregs[s->reg] = val; escc_update_parameters(s); From fd08ddb9cb050182c0f7c9d74b11038e9c479f4f Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 14 Nov 2021 11:35:36 +0100 Subject: [PATCH 12/79] linux-user: Split out do_getdents, do_getdents64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Retain all 3 implementations of getdents for now. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211114103539.298686-2-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 325 +++++++++++++++++++++++-------------------- 1 file changed, 172 insertions(+), 153 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 544f5b662f..a2f605dec4 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8137,6 +8137,176 @@ static int host_to_target_cpu_mask(const unsigned long *host_mask, return 0; } +#ifdef TARGET_NR_getdents +static int do_getdents(abi_long arg1, abi_long arg2, abi_long arg3) +{ + int ret; + +#ifdef EMULATE_GETDENTS_WITH_GETDENTS +# if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 + struct target_dirent *target_dirp; + struct linux_dirent *dirp; + abi_long count = arg3; + + dirp = g_try_malloc(count); + if (!dirp) { + return -TARGET_ENOMEM; + } + + ret = get_errno(sys_getdents(arg1, dirp, count)); + if (!is_error(ret)) { + struct linux_dirent *de; + struct target_dirent *tde; + int len = ret; + int reclen, treclen; + int count1, tnamelen; + + count1 = 0; + de = dirp; + target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0); + if (!target_dirp) { + return -TARGET_EFAULT; + } + tde = target_dirp; + while (len > 0) { + reclen = de->d_reclen; + tnamelen = reclen - offsetof(struct linux_dirent, d_name); + assert(tnamelen >= 0); + treclen = tnamelen + offsetof(struct target_dirent, d_name); + assert(count1 + treclen <= count); + tde->d_reclen = tswap16(treclen); + tde->d_ino = tswapal(de->d_ino); + tde->d_off = tswapal(de->d_off); + memcpy(tde->d_name, de->d_name, tnamelen); + de = (struct linux_dirent *)((char *)de + reclen); + len -= reclen; + tde = (struct target_dirent *)((char *)tde + treclen); + count1 += treclen; + } + ret = count1; + unlock_user(target_dirp, arg2, ret); + } + g_free(dirp); +# else + struct linux_dirent *dirp; + abi_long count = arg3; + + dirp = lock_user(VERIFY_WRITE, arg2, count, 0); + if (!dirp) { + return -TARGET_EFAULT; + } + ret = get_errno(sys_getdents(arg1, dirp, count)); + if (!is_error(ret)) { + struct linux_dirent *de; + int len = ret; + int reclen; + de = dirp; + while (len > 0) { + reclen = de->d_reclen; + if (reclen > len) { + break; + } + de->d_reclen = tswap16(reclen); + tswapls(&de->d_ino); + tswapls(&de->d_off); + de = (struct linux_dirent *)((char *)de + reclen); + len -= reclen; + } + } + unlock_user(dirp, arg2, ret); +# endif +#else + /* Implement getdents in terms of getdents64 */ + struct linux_dirent64 *dirp; + abi_long count = arg3; + + dirp = lock_user(VERIFY_WRITE, arg2, count, 0); + if (!dirp) { + return -TARGET_EFAULT; + } + ret = get_errno(sys_getdents64(arg1, dirp, count)); + if (!is_error(ret)) { + /* + * Convert the dirent64 structs to target dirent. We do this + * in-place, since we can guarantee that a target_dirent is no + * larger than a dirent64; however this means we have to be + * careful to read everything before writing in the new format. + */ + struct linux_dirent64 *de; + struct target_dirent *tde; + int len = ret; + int tlen = 0; + + de = dirp; + tde = (struct target_dirent *)dirp; + while (len > 0) { + int namelen, treclen; + int reclen = de->d_reclen; + uint64_t ino = de->d_ino; + int64_t off = de->d_off; + uint8_t type = de->d_type; + + namelen = strlen(de->d_name); + treclen = offsetof(struct target_dirent, d_name) + namelen + 2; + treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long)); + + memmove(tde->d_name, de->d_name, namelen + 1); + tde->d_ino = tswapal(ino); + tde->d_off = tswapal(off); + tde->d_reclen = tswap16(treclen); + /* + * The target_dirent type is in what was formerly a padding + * byte at the end of the structure: + */ + *(((char *)tde) + treclen - 1) = type; + + de = (struct linux_dirent64 *)((char *)de + reclen); + tde = (struct target_dirent *)((char *)tde + treclen); + len -= reclen; + tlen += treclen; + } + ret = tlen; + } + unlock_user(dirp, arg2, ret); +#endif + return ret; +} +#endif /* TARGET_NR_getdents */ + +#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64) +static int do_getdents64(abi_long arg1, abi_long arg2, abi_long arg3) +{ + struct linux_dirent64 *dirp; + abi_long count = arg3; + int ret; + + dirp = lock_user(VERIFY_WRITE, arg2, count, 0); + if (!dirp) { + return -TARGET_EFAULT; + } + ret = get_errno(sys_getdents64(arg1, dirp, count)); + if (!is_error(ret)) { + struct linux_dirent64 *de; + int len = ret; + int reclen; + de = dirp; + while (len > 0) { + reclen = de->d_reclen; + if (reclen > len) { + break; + } + de->d_reclen = tswap16(reclen); + tswap64s((uint64_t *)&de->d_ino); + tswap64s((uint64_t *)&de->d_off); + de = (struct linux_dirent64 *)((char *)de + reclen); + len -= reclen; + } + } + unlock_user(dirp, arg2, ret); + return ret; +} +#endif /* TARGET_NR_getdents64 */ + #if defined(TARGET_NR_pivot_root) && defined(__NR_pivot_root) _syscall2(int, pivot_root, const char *, new_root, const char *, put_old) #endif @@ -10227,162 +10397,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_getdents case TARGET_NR_getdents: -#ifdef EMULATE_GETDENTS_WITH_GETDENTS -#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 - { - struct target_dirent *target_dirp; - struct linux_dirent *dirp; - abi_long count = arg3; - - dirp = g_try_malloc(count); - if (!dirp) { - return -TARGET_ENOMEM; - } - - ret = get_errno(sys_getdents(arg1, dirp, count)); - if (!is_error(ret)) { - struct linux_dirent *de; - struct target_dirent *tde; - int len = ret; - int reclen, treclen; - int count1, tnamelen; - - count1 = 0; - de = dirp; - if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0))) - return -TARGET_EFAULT; - tde = target_dirp; - while (len > 0) { - reclen = de->d_reclen; - tnamelen = reclen - offsetof(struct linux_dirent, d_name); - assert(tnamelen >= 0); - treclen = tnamelen + offsetof(struct target_dirent, d_name); - assert(count1 + treclen <= count); - tde->d_reclen = tswap16(treclen); - tde->d_ino = tswapal(de->d_ino); - tde->d_off = tswapal(de->d_off); - memcpy(tde->d_name, de->d_name, tnamelen); - de = (struct linux_dirent *)((char *)de + reclen); - len -= reclen; - tde = (struct target_dirent *)((char *)tde + treclen); - count1 += treclen; - } - ret = count1; - unlock_user(target_dirp, arg2, ret); - } - g_free(dirp); - } -#else - { - struct linux_dirent *dirp; - abi_long count = arg3; - - if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0))) - return -TARGET_EFAULT; - ret = get_errno(sys_getdents(arg1, dirp, count)); - if (!is_error(ret)) { - struct linux_dirent *de; - int len = ret; - int reclen; - de = dirp; - while (len > 0) { - reclen = de->d_reclen; - if (reclen > len) - break; - de->d_reclen = tswap16(reclen); - tswapls(&de->d_ino); - tswapls(&de->d_off); - de = (struct linux_dirent *)((char *)de + reclen); - len -= reclen; - } - } - unlock_user(dirp, arg2, ret); - } -#endif -#else - /* Implement getdents in terms of getdents64 */ - { - struct linux_dirent64 *dirp; - abi_long count = arg3; - - dirp = lock_user(VERIFY_WRITE, arg2, count, 0); - if (!dirp) { - return -TARGET_EFAULT; - } - ret = get_errno(sys_getdents64(arg1, dirp, count)); - if (!is_error(ret)) { - /* Convert the dirent64 structs to target dirent. We do this - * in-place, since we can guarantee that a target_dirent is no - * larger than a dirent64; however this means we have to be - * careful to read everything before writing in the new format. - */ - struct linux_dirent64 *de; - struct target_dirent *tde; - int len = ret; - int tlen = 0; - - de = dirp; - tde = (struct target_dirent *)dirp; - while (len > 0) { - int namelen, treclen; - int reclen = de->d_reclen; - uint64_t ino = de->d_ino; - int64_t off = de->d_off; - uint8_t type = de->d_type; - - namelen = strlen(de->d_name); - treclen = offsetof(struct target_dirent, d_name) - + namelen + 2; - treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long)); - - memmove(tde->d_name, de->d_name, namelen + 1); - tde->d_ino = tswapal(ino); - tde->d_off = tswapal(off); - tde->d_reclen = tswap16(treclen); - /* The target_dirent type is in what was formerly a padding - * byte at the end of the structure: - */ - *(((char *)tde) + treclen - 1) = type; - - de = (struct linux_dirent64 *)((char *)de + reclen); - tde = (struct target_dirent *)((char *)tde + treclen); - len -= reclen; - tlen += treclen; - } - ret = tlen; - } - unlock_user(dirp, arg2, ret); - } -#endif - return ret; + return do_getdents(arg1, arg2, arg3); #endif /* TARGET_NR_getdents */ #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64) case TARGET_NR_getdents64: - { - struct linux_dirent64 *dirp; - abi_long count = arg3; - if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0))) - return -TARGET_EFAULT; - ret = get_errno(sys_getdents64(arg1, dirp, count)); - if (!is_error(ret)) { - struct linux_dirent64 *de; - int len = ret; - int reclen; - de = dirp; - while (len > 0) { - reclen = de->d_reclen; - if (reclen > len) - break; - de->d_reclen = tswap16(reclen); - tswap64s((uint64_t *)&de->d_ino); - tswap64s((uint64_t *)&de->d_off); - de = (struct linux_dirent64 *)((char *)de + reclen); - len -= reclen; - } - } - unlock_user(dirp, arg2, ret); - } - return ret; + return do_getdents64(arg1, arg2, arg3); #endif /* TARGET_NR_getdents64 */ #if defined(TARGET_NR__newselect) case TARGET_NR__newselect: From 540a736f54a5dffb0851f2adf455f50869b409a1 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 14 Nov 2021 11:35:37 +0100 Subject: [PATCH 13/79] linux-user: Always use flexible arrays for dirent d_name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We currently use a flexible array member for target_dirent, but use incorrectly fixed length arrays for target_dirent64, linux_dirent and linux_dirent64. This requires that we adjust the definition of the VFAT READDIR ioctls which hard-code the 256 namelen size into the ioctl constant. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211114103539.298686-3-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 6 ++++-- linux-user/syscall_defs.h | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a2f605dec4..499415ad81 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -197,8 +197,10 @@ //#define DEBUG_ERESTARTSYS //#include -#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2]) -#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2]) +#define VFAT_IOCTL_READDIR_BOTH \ + _IOC(_IOC_READ, 'r', 1, (sizeof(struct linux_dirent) + 256) * 2) +#define VFAT_IOCTL_READDIR_SHORT \ + _IOC(_IOC_READ, 'r', 2, (sizeof(struct linux_dirent) + 256) * 2) #undef _syscall0 #undef _syscall1 diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index a5ce487dcc..98b09ee6d6 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -441,7 +441,7 @@ struct target_dirent64 { int64_t d_off; unsigned short d_reclen; unsigned char d_type; - char d_name[256]; + char d_name[]; }; @@ -2714,7 +2714,7 @@ struct linux_dirent { long d_ino; unsigned long d_off; unsigned short d_reclen; - char d_name[256]; /* We must not include limits.h! */ + char d_name[]; }; struct linux_dirent64 { @@ -2722,7 +2722,7 @@ struct linux_dirent64 { int64_t d_off; unsigned short d_reclen; unsigned char d_type; - char d_name[256]; + char d_name[]; }; struct target_mq_attr { From 1962cb0029197bc0cd4bb0461171cda677e64966 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 14 Nov 2021 11:35:38 +0100 Subject: [PATCH 14/79] linux-user: Fix member types of target_dirent64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The host uint64_t (etc) does not have the correct alignment constraint as the guest: use abi_* types. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211114103539.298686-4-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/syscall_defs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 98b09ee6d6..41aaafbac1 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -437,9 +437,9 @@ struct target_dirent { }; struct target_dirent64 { - uint64_t d_ino; - int64_t d_off; - unsigned short d_reclen; + abi_ullong d_ino; + abi_llong d_off; + abi_ushort d_reclen; unsigned char d_type; char d_name[]; }; From aee14c77f42533f2480dfa8552f531efde6c19ee Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 14 Nov 2021 11:35:39 +0100 Subject: [PATCH 15/79] linux-user: Rewrite do_getdents, do_getdents64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Always allocate host storage; this ensures that the struct is sufficiently aligned for the host. Merge the three host implementations of getdents via a few ifdefs. Utilize the same method for do_getdents64. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/704 Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211114103539.298686-5-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 259 ++++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 138 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 499415ad81..f1cfcc8104 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8140,172 +8140,155 @@ static int host_to_target_cpu_mask(const unsigned long *host_mask, } #ifdef TARGET_NR_getdents -static int do_getdents(abi_long arg1, abi_long arg2, abi_long arg3) +static int do_getdents(abi_long dirfd, abi_long arg2, abi_long count) { - int ret; + g_autofree void *hdirp = NULL; + void *tdirp; + int hlen, hoff, toff; + int hreclen, treclen; + off64_t prev_diroff = 0; -#ifdef EMULATE_GETDENTS_WITH_GETDENTS -# if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 - struct target_dirent *target_dirp; - struct linux_dirent *dirp; - abi_long count = arg3; - - dirp = g_try_malloc(count); - if (!dirp) { + hdirp = g_try_malloc(count); + if (!hdirp) { return -TARGET_ENOMEM; } - ret = get_errno(sys_getdents(arg1, dirp, count)); - if (!is_error(ret)) { - struct linux_dirent *de; - struct target_dirent *tde; - int len = ret; - int reclen, treclen; - int count1, tnamelen; +#ifdef EMULATE_GETDENTS_WITH_GETDENTS + hlen = sys_getdents(dirfd, hdirp, count); +#else + hlen = sys_getdents64(dirfd, hdirp, count); +#endif - count1 = 0; - de = dirp; - target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0); - if (!target_dirp) { - return -TARGET_EFAULT; - } - tde = target_dirp; - while (len > 0) { - reclen = de->d_reclen; - tnamelen = reclen - offsetof(struct linux_dirent, d_name); - assert(tnamelen >= 0); - treclen = tnamelen + offsetof(struct target_dirent, d_name); - assert(count1 + treclen <= count); - tde->d_reclen = tswap16(treclen); - tde->d_ino = tswapal(de->d_ino); - tde->d_off = tswapal(de->d_off); - memcpy(tde->d_name, de->d_name, tnamelen); - de = (struct linux_dirent *)((char *)de + reclen); - len -= reclen; - tde = (struct target_dirent *)((char *)tde + treclen); - count1 += treclen; - } - ret = count1; - unlock_user(target_dirp, arg2, ret); + hlen = get_errno(hlen); + if (is_error(hlen)) { + return hlen; } - g_free(dirp); -# else - struct linux_dirent *dirp; - abi_long count = arg3; - dirp = lock_user(VERIFY_WRITE, arg2, count, 0); - if (!dirp) { + tdirp = lock_user(VERIFY_WRITE, arg2, count, 0); + if (!tdirp) { return -TARGET_EFAULT; } - ret = get_errno(sys_getdents(arg1, dirp, count)); - if (!is_error(ret)) { - struct linux_dirent *de; - int len = ret; - int reclen; - de = dirp; - while (len > 0) { - reclen = de->d_reclen; - if (reclen > len) { + + for (hoff = toff = 0; hoff < hlen; hoff += hreclen, toff += treclen) { +#ifdef EMULATE_GETDENTS_WITH_GETDENTS + struct linux_dirent *hde = hdirp + hoff; +#else + struct linux_dirent64 *hde = hdirp + hoff; +#endif + struct target_dirent *tde = tdirp + toff; + int namelen; + uint8_t type; + + namelen = strlen(hde->d_name); + hreclen = hde->d_reclen; + treclen = offsetof(struct target_dirent, d_name) + namelen + 2; + treclen = QEMU_ALIGN_UP(treclen, __alignof(struct target_dirent)); + + if (toff + treclen > count) { + /* + * If the host struct is smaller than the target struct, or + * requires less alignment and thus packs into less space, + * then the host can return more entries than we can pass + * on to the guest. + */ + if (toff == 0) { + toff = -TARGET_EINVAL; /* result buffer is too small */ break; } - de->d_reclen = tswap16(reclen); - tswapls(&de->d_ino); - tswapls(&de->d_off); - de = (struct linux_dirent *)((char *)de + reclen); - len -= reclen; - } - } - unlock_user(dirp, arg2, ret); -# endif -#else - /* Implement getdents in terms of getdents64 */ - struct linux_dirent64 *dirp; - abi_long count = arg3; - - dirp = lock_user(VERIFY_WRITE, arg2, count, 0); - if (!dirp) { - return -TARGET_EFAULT; - } - ret = get_errno(sys_getdents64(arg1, dirp, count)); - if (!is_error(ret)) { - /* - * Convert the dirent64 structs to target dirent. We do this - * in-place, since we can guarantee that a target_dirent is no - * larger than a dirent64; however this means we have to be - * careful to read everything before writing in the new format. - */ - struct linux_dirent64 *de; - struct target_dirent *tde; - int len = ret; - int tlen = 0; - - de = dirp; - tde = (struct target_dirent *)dirp; - while (len > 0) { - int namelen, treclen; - int reclen = de->d_reclen; - uint64_t ino = de->d_ino; - int64_t off = de->d_off; - uint8_t type = de->d_type; - - namelen = strlen(de->d_name); - treclen = offsetof(struct target_dirent, d_name) + namelen + 2; - treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long)); - - memmove(tde->d_name, de->d_name, namelen + 1); - tde->d_ino = tswapal(ino); - tde->d_off = tswapal(off); - tde->d_reclen = tswap16(treclen); /* - * The target_dirent type is in what was formerly a padding - * byte at the end of the structure: + * Return what we have, resetting the file pointer to the + * location of the first record not returned. */ - *(((char *)tde) + treclen - 1) = type; - - de = (struct linux_dirent64 *)((char *)de + reclen); - tde = (struct target_dirent *)((char *)tde + treclen); - len -= reclen; - tlen += treclen; + lseek64(dirfd, prev_diroff, SEEK_SET); + break; } - ret = tlen; - } - unlock_user(dirp, arg2, ret); + + prev_diroff = hde->d_off; + tde->d_ino = tswapal(hde->d_ino); + tde->d_off = tswapal(hde->d_off); + tde->d_reclen = tswap16(treclen); + memcpy(tde->d_name, hde->d_name, namelen + 1); + + /* + * The getdents type is in what was formerly a padding byte at the + * end of the structure. + */ +#ifdef EMULATE_GETDENTS_WITH_GETDENTS + type = *((uint8_t *)hde + hreclen - 1); +#else + type = hde->d_type; #endif - return ret; + *((uint8_t *)tde + treclen - 1) = type; + } + + unlock_user(tdirp, arg2, toff); + return toff; } #endif /* TARGET_NR_getdents */ #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64) -static int do_getdents64(abi_long arg1, abi_long arg2, abi_long arg3) +static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count) { - struct linux_dirent64 *dirp; - abi_long count = arg3; - int ret; + g_autofree void *hdirp = NULL; + void *tdirp; + int hlen, hoff, toff; + int hreclen, treclen; + off64_t prev_diroff = 0; - dirp = lock_user(VERIFY_WRITE, arg2, count, 0); - if (!dirp) { + hdirp = g_try_malloc(count); + if (!hdirp) { + return -TARGET_ENOMEM; + } + + hlen = get_errno(sys_getdents64(dirfd, hdirp, count)); + if (is_error(hlen)) { + return hlen; + } + + tdirp = lock_user(VERIFY_WRITE, arg2, count, 0); + if (!tdirp) { return -TARGET_EFAULT; } - ret = get_errno(sys_getdents64(arg1, dirp, count)); - if (!is_error(ret)) { - struct linux_dirent64 *de; - int len = ret; - int reclen; - de = dirp; - while (len > 0) { - reclen = de->d_reclen; - if (reclen > len) { + + for (hoff = toff = 0; hoff < hlen; hoff += hreclen, toff += treclen) { + struct linux_dirent64 *hde = hdirp + hoff; + struct target_dirent64 *tde = tdirp + toff; + int namelen; + + namelen = strlen(hde->d_name) + 1; + hreclen = hde->d_reclen; + treclen = offsetof(struct target_dirent64, d_name) + namelen; + treclen = QEMU_ALIGN_UP(treclen, __alignof(struct target_dirent64)); + + if (toff + treclen > count) { + /* + * If the host struct is smaller than the target struct, or + * requires less alignment and thus packs into less space, + * then the host can return more entries than we can pass + * on to the guest. + */ + if (toff == 0) { + toff = -TARGET_EINVAL; /* result buffer is too small */ break; } - de->d_reclen = tswap16(reclen); - tswap64s((uint64_t *)&de->d_ino); - tswap64s((uint64_t *)&de->d_off); - de = (struct linux_dirent64 *)((char *)de + reclen); - len -= reclen; + /* + * Return what we have, resetting the file pointer to the + * location of the first record not returned. + */ + lseek64(dirfd, prev_diroff, SEEK_SET); + break; } + + prev_diroff = hde->d_off; + tde->d_ino = tswap64(hde->d_ino); + tde->d_off = tswap64(hde->d_off); + tde->d_reclen = tswap16(treclen); + tde->d_type = hde->d_type; + memcpy(tde->d_name, hde->d_name, namelen); } - unlock_user(dirp, arg2, ret); - return ret; + + unlock_user(tdirp, arg2, toff); + return toff; } #endif /* TARGET_NR_getdents64 */ From 6b717a8d4482fa88fb2a40b5afd5a55e7a0ba412 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 19 Nov 2021 11:25:49 +0100 Subject: [PATCH 16/79] hw/misc/sifive_u_otp: Use IF_PFLASH for the OTP device instead of IF_NONE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Configuring a drive with "if=none" is meant for creation of a backend only, it should not get automatically assigned to a device frontend. Use "if=pflash" for the One-Time-Programmable device instead (like it is e.g. also done for the efuse device in hw/arm/xlnx-zcu102.c). Since the old way of configuring the device has already been published with the previous QEMU versions, we cannot remove this immediately, but have to deprecate it and support it for at least two more releases. Signed-off-by: Thomas Huth Acked-by: Philippe Mathieu-Daudé Reviewed-by: Markus Armbruster Reviewed-by: Alistair Francis Message-id: 20211119102549.217755-1-thuth@redhat.com Signed-off-by: Alistair Francis --- docs/about/deprecated.rst | 6 ++++++ hw/misc/sifive_u_otp.c | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index c03fcf951f..ff7488cb63 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -192,6 +192,12 @@ as short-form boolean values, and passed to plugins as ``arg_name=on``. However, short-form booleans are deprecated and full explicit ``arg_name=on`` form is preferred. +``-drive if=none`` for the sifive_u OTP device (since 6.2) +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +Using ``-drive if=none`` to configure the OTP device of the sifive_u +RISC-V machine is deprecated. Use ``-drive if=pflash`` instead. + QEMU Machine Protocol (QMP) commands ------------------------------------ diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c index 18aa0bd55d..cf6098ff2c 100644 --- a/hw/misc/sifive_u_otp.c +++ b/hw/misc/sifive_u_otp.c @@ -209,7 +209,14 @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp) TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); - dinfo = drive_get_next(IF_NONE); + dinfo = drive_get_next(IF_PFLASH); + if (!dinfo) { + dinfo = drive_get_next(IF_NONE); + if (dinfo) { + warn_report("using \"-drive if=none\" for the OTP is deprecated, " + "use \"-drive if=pflash\" instead."); + } + } if (dinfo) { int ret; uint64_t perm; From 526e7443027c71fe7b04c29df529e1f9f425f9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 19 Nov 2021 11:47:57 +0100 Subject: [PATCH 17/79] hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Once a "One Time Programmable" is programmed, it shouldn't be reset. Do not re-initialize the OTP content in the DeviceReset handler, initialize it once in the DeviceRealize one. Fixes: 9fb45c62ae8 ("riscv: sifive: Implement a model for SiFive FU540 OTP") Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-Id: <20211119104757.331579-1-f4bug@amsat.org> Signed-off-by: Alistair Francis --- hw/misc/sifive_u_otp.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c index cf6098ff2c..52fdb750c0 100644 --- a/hw/misc/sifive_u_otp.c +++ b/hw/misc/sifive_u_otp.c @@ -242,14 +242,10 @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp) if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) { error_setg(errp, "failed to read the initial flash content"); + return; } } } -} - -static void sifive_u_otp_reset(DeviceState *dev) -{ - SiFiveUOTPState *s = SIFIVE_U_OTP(dev); /* Initialize all fuses' initial value to 0xFFs */ memset(s->fuse, 0xff, sizeof(s->fuse)); @@ -266,13 +262,15 @@ static void sifive_u_otp_reset(DeviceState *dev) serial_data = s->serial; if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD, &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) { - error_report("write error index<%d>", index); + error_setg(errp, "failed to write index<%d>", index); + return; } serial_data = ~(s->serial); if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD, &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) { - error_report("write error index<%d>", index + 1); + error_setg(errp, "failed to write index<%d>", index + 1); + return; } } @@ -286,7 +284,6 @@ static void sifive_u_otp_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, sifive_u_otp_properties); dc->realize = sifive_u_otp_realize; - dc->reset = sifive_u_otp_reset; } static const TypeInfo sifive_u_otp_info = { From 802ae45e94151a6d3ee20eadcb865cf6c875df34 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Sun, 21 Nov 2021 16:17:11 +0100 Subject: [PATCH 18/79] linux-user: fix Coverity CID 1464101 target_mmap() can fail and return -1, but we don't check for that and instead assume it's always valid. Fixes: db2af69d6ba8 ("linux-user: Add infrastructure for a signal trampoline page") Cc: richard.henderson@linaro.org Reported-by: Peter Maydell Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson Message-Id: <20211121151711.331653-1-laurent@vivier.eu> Signed-off-by: Laurent Vivier --- linux-user/elfload.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 5da8c02d08..767f54c76d 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -3254,9 +3254,13 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) * Otherwise, allocate a private page to hold them. */ if (TARGET_ARCH_HAS_SIGTRAMP_PAGE) { - abi_ulong tramp_page = target_mmap(0, TARGET_PAGE_SIZE, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); + abi_long tramp_page = target_mmap(0, TARGET_PAGE_SIZE, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (tramp_page == -1) { + return -errno; + } + setup_sigtramp(tramp_page); target_mprotect(tramp_page, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC); } From 4323118cadc5a316f73b5b0a60b5789ed9201369 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Sun, 21 Nov 2021 01:55:03 -0500 Subject: [PATCH 19/79] ui: fix incorrect scaling on highdpi with gtk/opengl Signed-off-by: Alexander Orzechowski Message-Id: <20211121065504.29101-2-orzechowski.alexander@gmail.com> [ kraxel: codestyle fix ] Signed-off-by: Gerd Hoffmann --- ui/gtk-gl-area.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index 461da7712f..01e4e74ee3 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -41,15 +41,16 @@ void gd_gl_area_draw(VirtualConsole *vc) #ifdef CONFIG_GBM QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; #endif - int ww, wh, y1, y2; + int ww, wh, ws, y1, y2; if (!vc->gfx.gls) { return; } gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area)); - ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area); - wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area); + ws = gdk_window_get_scale_factor(gtk_widget_get_window(vc->gfx.drawing_area)); + ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area) * ws; + wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area) * ws; if (vc->gfx.scanout_mode) { if (!vc->gfx.guest_fb.framebuffer) { From f14aab420c58b57e07189d6d9e6d3fbfab4761a6 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Sun, 21 Nov 2021 01:55:04 -0500 Subject: [PATCH 20/79] ui: fix incorrect pointer position on highdpi with gtk Signed-off-by: Alexander Orzechowski Message-Id: <20211121065504.29101-3-orzechowski.alexander@gmail.com> [ kraxel: codestyle fix ] Signed-off-by: Gerd Hoffmann --- ui/gtk.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ui/gtk.c b/ui/gtk.c index d2892ea6b4..dc4a1491f0 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -838,10 +838,11 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, { VirtualConsole *vc = opaque; GtkDisplayState *s = vc->s; + GdkWindow *window; int x, y; int mx, my; int fbh, fbw; - int ww, wh; + int ww, wh, ws; if (!vc->gfx.ds) { return TRUE; @@ -850,8 +851,10 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x; fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y; - ww = gdk_window_get_width(gtk_widget_get_window(vc->gfx.drawing_area)); - wh = gdk_window_get_height(gtk_widget_get_window(vc->gfx.drawing_area)); + window = gtk_widget_get_window(vc->gfx.drawing_area); + ww = gdk_window_get_width(window); + wh = gdk_window_get_height(window); + ws = gdk_window_get_scale_factor(window); mx = my = 0; if (ww > fbw) { @@ -861,8 +864,8 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, my = (wh - fbh) / 2; } - x = (motion->x - mx) / vc->gfx.scale_x; - y = (motion->y - my) / vc->gfx.scale_y; + x = (motion->x - mx) / vc->gfx.scale_x * ws; + y = (motion->y - my) / vc->gfx.scale_y * ws; if (qemu_input_is_absolute()) { if (x < 0 || y < 0 || From c3abdb2faff62e3ded21bf8c3ef493ed70785623 Mon Sep 17 00:00:00 2001 From: Dongwon Kim Date: Sun, 21 Nov 2021 09:22:37 -0800 Subject: [PATCH 21/79] ui/gtk: graphic_hw_gl_flushed after closing dmabuf->fence_fd The dmabuf often becomes invalid right after unblocking pipeline and graphic_hw_gl_flushed in case a new scanout blob is submitted because the dmabuf associated with the current guest scanout is freed after swapping. So both graphic_hw_gl_block and graphic_hw_gl_flushed should be executed after closing fence_fd for the current dmabuf. Cc: Gerd Hoffmann Cc: Vivek Kasireddy Signed-off-by: Dongwon Kim Message-Id: <20211121172237.14937-1-dongwon.kim@intel.com> Signed-off-by: Gerd Hoffmann --- ui/gtk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/gtk.c b/ui/gtk.c index dc4a1491f0..428f02f2df 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -589,11 +589,11 @@ void gd_hw_gl_flushed(void *vcon) VirtualConsole *vc = vcon; QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; - graphic_hw_gl_block(vc->gfx.dcl.con, false); - graphic_hw_gl_flushed(vc->gfx.dcl.con); qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL); close(dmabuf->fence_fd); dmabuf->fence_fd = -1; + graphic_hw_gl_block(vc->gfx.dcl.con, false); + graphic_hw_gl_flushed(vc->gfx.dcl.con); } /** DisplayState Callbacks (opengl version) **/ From 2e572baf659f5a457c876c6b2d02a217afb401c5 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Wed, 10 Nov 2021 11:38:00 +0100 Subject: [PATCH 22/79] ui/vnc-clipboard: fix adding notifier twice vnc_server_cut_text_caps() is not guaranteed to be called only once. If it called twice, we finally call notifier_list_add() twice with same element. Which leads to loopback QLIST. So, on next notifier_list_notify() we'll loop forever and QEMU stuck. So, let's only register new notifier if it's not yet registered. Note, that similar check is used in vdagent_chr_recv_caps() (before call qemu_clipboard_peer_register()), and also before qemu_clipboard_peer_unregister() call in vdagent_disconnect() and in vnc_disconnect_finish(). Signed-off-by: Vladimir Sementsov-Ogievskiy Message-Id: <20211110103800.2266729-1-vsementsov@virtuozzo.com> Signed-off-by: Gerd Hoffmann --- ui/vnc-clipboard.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ui/vnc-clipboard.c b/ui/vnc-clipboard.c index 9f077965d0..67284b556c 100644 --- a/ui/vnc-clipboard.c +++ b/ui/vnc-clipboard.c @@ -316,8 +316,10 @@ void vnc_server_cut_text_caps(VncState *vs) caps[1] = 0; vnc_clipboard_send(vs, 2, caps); - vs->cbpeer.name = "vnc"; - vs->cbpeer.update.notify = vnc_clipboard_notify; - vs->cbpeer.request = vnc_clipboard_request; - qemu_clipboard_peer_register(&vs->cbpeer); + if (!vs->cbpeer.update.notify) { + vs->cbpeer.name = "vnc"; + vs->cbpeer.update.notify = vnc_clipboard_notify; + vs->cbpeer.request = vnc_clipboard_request; + qemu_clipboard_peer_register(&vs->cbpeer); + } } From 4067691a2fed9a7639b1264b07c131d8e11f2b4f Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Tue, 16 Nov 2021 08:28:40 +0100 Subject: [PATCH 23/79] migration: fix dump-vmstate with modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To work correctly -dump-vmstate and vmstate-static-checker.py need to dump all the supported vmstates. But as some devices can be modules, they are not loaded at startup and not dumped. Fix that by loading all available modules before dumping the machine vmstate. Fixes: 7ab6e7fcce97 ("qdev: device module support") Cc: kraxel@redhat.com Signed-off-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211116072840.132731-1-lvivier@redhat.com> Signed-off-by: Gerd Hoffmann --- softmmu/vl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/softmmu/vl.c b/softmmu/vl.c index 1159a64bce..620a1f1367 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -3766,6 +3766,7 @@ void qemu_init(int argc, char **argv, char **envp) if (vmstate_dump_file) { /* dump and exit */ + module_load_qom_all(); dump_vmstate_json_to_file(vmstate_dump_file); exit(0); } From d612405ed2a1163a142f94552a9874ad4b02de30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 17 Nov 2021 18:43:31 +0100 Subject: [PATCH 24/79] hw/i386/microvm: Reduce annoying debug message in dt_setup_microvm() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: f5918a99283 ("microvm: add device tree support.") Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Sergio Lopez Reviewed-by: Darren Kenny Message-Id: <20211117174331.1715144-1-philmd@redhat.com> Signed-off-by: Gerd Hoffmann --- hw/i386/microvm-dt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/i386/microvm-dt.c b/hw/i386/microvm-dt.c index 875ba91963..6ee6c42904 100644 --- a/hw/i386/microvm-dt.c +++ b/hw/i386/microvm-dt.c @@ -327,7 +327,9 @@ void dt_setup_microvm(MicrovmMachineState *mms) dt_setup_sys_bus(mms); /* add to fw_cfg */ - fprintf(stderr, "%s: add etc/fdt to fw_cfg\n", __func__); + if (debug) { + fprintf(stderr, "%s: add etc/fdt to fw_cfg\n", __func__); + } fw_cfg_add_file(x86ms->fw_cfg, "etc/fdt", mms->fdt, size); if (debug) { From 1b38ccc9a1fa865a8838c89216dc36df87e9c9d5 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 8 Nov 2021 14:07:17 +0100 Subject: [PATCH 25/79] microvm: add missing g_free() call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: CID 1465240 Signed-off-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211108130718.840216-2-kraxel@redhat.com> --- hw/i386/microvm-dt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/i386/microvm-dt.c b/hw/i386/microvm-dt.c index 6ee6c42904..a6a59a6e12 100644 --- a/hw/i386/microvm-dt.c +++ b/hw/i386/microvm-dt.c @@ -143,6 +143,8 @@ static void dt_add_pcie(MicrovmMachineState *mms) nr_pcie_buses = PCIE_ECAM_SIZE / PCIE_MMCFG_SIZE_MIN; qemu_fdt_setprop_cells(mms->fdt, nodename, "bus-range", 0, nr_pcie_buses - 1); + + g_free(nodename); } static void dt_add_ioapic(MicrovmMachineState *mms, SysBusDevice *dev) From b9e5628ca5d42994cc6f82752d9bf0bc98f51f64 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 8 Nov 2021 14:07:18 +0100 Subject: [PATCH 26/79] microvm: check g_file_set_contents() return value Fixes: CID 1465239 Signed-off-by: Gerd Hoffmann Message-Id: <20211108130718.840216-3-kraxel@redhat.com> --- hw/i386/microvm-dt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/i386/microvm-dt.c b/hw/i386/microvm-dt.c index a6a59a6e12..9c3c4995b4 100644 --- a/hw/i386/microvm-dt.c +++ b/hw/i386/microvm-dt.c @@ -336,7 +336,10 @@ void dt_setup_microvm(MicrovmMachineState *mms) if (debug) { fprintf(stderr, "%s: writing microvm.fdt\n", __func__); - g_file_set_contents("microvm.fdt", mms->fdt, size, NULL); + if (!g_file_set_contents("microvm.fdt", mms->fdt, size, NULL)) { + fprintf(stderr, "%s: writing microvm.fdt failed\n", __func__); + return; + } int ret = system("dtc -I dtb -O dts microvm.fdt"); if (ret != 0) { fprintf(stderr, "%s: oops, dtc not installed?\n", __func__); From 1644cccea5c71b02b9cf8f78b780e7069a29b189 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 17 Nov 2021 11:02:29 -0600 Subject: [PATCH 27/79] nbd/server: Don't complain on certain client disconnects When a client disconnects abruptly, but did not have any pending requests (for example, when using nbdsh without calling h.shutdown), we used to output the following message: $ qemu-nbd -f raw file $ nbdsh -u 'nbd://localhost:10809' -c 'h.trim(1,0)' qemu-nbd: Disconnect client, due to: Failed to read request: Unexpected end-of-file before all bytes were read Then in commit f148ae7, we refactored nbd_receive_request() to use nbd_read_eof(); when this returns 0, we regressed into tracing uninitialized memory (if tracing is enabled) and reporting a less-specific: qemu-nbd: Disconnect client, due to: Request handling failed in intermediate state Note that with Unix sockets, we have yet another error message, unchanged by the 6.0 regression: $ qemu-nbd -k /tmp/sock -f raw file $ nbdsh -u 'nbd+unix:///?socket=/tmp/sock' -c 'h.trim(1,0)' qemu-nbd: Disconnect client, due to: Failed to send reply: Unable to write to socket: Broken pipe But in all cases, the error message goes away if the client performs a soft shutdown by using NBD_CMD_DISC, rather than a hard shutdown by abrupt disconnect: $ nbdsh -u 'nbd://localhost:10809' -c 'h.trim(1,0)' -c 'h.shutdown()' This patch fixes things to avoid uninitialized memory, and in general avoids warning about a client that does a hard shutdown when not in the middle of a packet. A client that aborts mid-request, or which does not read the full server's reply, can still result in warnings, but those are indeed much more unusual situations. CC: qemu-stable@nongnu.org Fixes: f148ae7d36 ("nbd/server: Quiesce coroutines on context switch", v6.0.0) Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy [eblake: defer unrelated typo fixes to later patch] Message-Id: <20211117170230.1128262-2-eblake@redhat.com> Signed-off-by: Eric Blake --- nbd/server.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nbd/server.c b/nbd/server.c index d9164ee6d0..74ba487094 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1418,6 +1418,9 @@ static int nbd_receive_request(NBDClient *client, NBDRequest *request, if (ret < 0) { return ret; } + if (ret == 0) { + return -EIO; + } /* Request [ 0 .. 3] magic (NBD_REQUEST_MAGIC) From e35574226a63f29e32eda8da5cc14832f19850e2 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 17 Nov 2021 11:02:30 -0600 Subject: [PATCH 28/79] nbd/server: Simplify zero and trim Now that the block layer supports 64-bit operations (see commit 2800637a and friends, new to v6.2), we no longer have to self-fragment requests larger than 2G, reverting the workaround added in 890cbccb08 ("nbd: Fix large trim/zero requests", v5.1.0). Signed-off-by: Eric Blake Message-Id: <20211117170230.1128262-3-eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy --- nbd/server.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index 74ba487094..4630dd7322 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -2509,16 +2509,8 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, if (request->flags & NBD_CMD_FLAG_FAST_ZERO) { flags |= BDRV_REQ_NO_FALLBACK; } - ret = 0; - /* FIXME simplify this when blk_pwrite_zeroes switches to 64-bit */ - while (ret >= 0 && request->len) { - int align = client->check_align ?: 1; - int len = MIN(request->len, QEMU_ALIGN_DOWN(BDRV_REQUEST_MAX_BYTES, - align)); - ret = blk_pwrite_zeroes(exp->common.blk, request->from, len, flags); - request->len -= len; - request->from += len; - } + ret = blk_pwrite_zeroes(exp->common.blk, request->from, request->len, + flags); return nbd_send_generic_reply(client, request->handle, ret, "writing to file failed", errp); @@ -2532,16 +2524,7 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, "flush failed", errp); case NBD_CMD_TRIM: - ret = 0; - /* FIXME simplify this when blk_co_pdiscard switches to 64-bit */ - while (ret >= 0 && request->len) { - int align = client->check_align ?: 1; - int len = MIN(request->len, QEMU_ALIGN_DOWN(BDRV_REQUEST_MAX_BYTES, - align)); - ret = blk_co_pdiscard(exp->common.blk, request->from, len); - request->len -= len; - request->from += len; - } + ret = blk_co_pdiscard(exp->common.blk, request->from, request->len); if (ret >= 0 && request->flags & NBD_CMD_FLAG_FUA) { ret = blk_co_flush(exp->common.blk); } From 4825eaae4fdd56fba0febdfbdd7bf9684ae3ee0d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 22 Nov 2021 13:41:48 +0000 Subject: [PATCH 29/79] Revert "arm: tcg: Adhere to SMCCC 1.3 section 5.2" This reverts commit 9fcd15b9193e819b6cc2fd0a45e3506148812bb4. This change turns out to cause regressions, for instance on the imx6ul boards as described here: https://lore.kernel.org/qemu-devel/c8b89685-7490-328b-51a3-48711c140a84@tribudubois.net/ The primary cause of that regression is that the guest code running at EL3 expects SMCs (not related to PSCI) to do what they would if our PSCI emulation was not present at all, but after this change they instead set a value in R0/X0 and continue. We could fix that by a refactoring that allowed us to only turn on the PSCI emulation if we weren't booting the guest at EL3, but there is a more tangled problem with the highbank board, which: (1) wants to enable PSCI emulation (2) has a bit of guest code that it wants to run at EL3 and to perform SMC calls that trap to the monitor vector table: this is the boot stub code that is written to memory by arm_write_secure_board_setup_dummy_smc() and which the highbank board enables by setting bootinfo->secure_board_setup We can't satisfy both of those and also have the PSCI emulation handle all SMC instruction executions regardless of function identifier value. This is too tricky to try to sort out before 6.2 is released; revert this commit so we can take the time to get it right in the 7.0 release. Signed-off-by: Peter Maydell Message-id: 20211119163419.557623-1-peter.maydell@linaro.org --- target/arm/psci.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/target/arm/psci.c b/target/arm/psci.c index b279c0b9a4..6709e28013 100644 --- a/target/arm/psci.c +++ b/target/arm/psci.c @@ -27,13 +27,15 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type) { - /* - * Return true if the exception type matches the configured PSCI conduit. - * This is called before the SMC/HVC instruction is executed, to decide - * whether we should treat it as a PSCI call or with the architecturally + /* Return true if the r0/x0 value indicates a PSCI call and + * the exception type matches the configured PSCI conduit. This is + * called before the SMC/HVC instruction is executed, to decide whether + * we should treat it as a PSCI call or with the architecturally * defined behaviour for an SMC or HVC (which might be UNDEF or trap * to EL2 or to EL3). */ + CPUARMState *env = &cpu->env; + uint64_t param = is_a64(env) ? env->xregs[0] : env->regs[0]; switch (excp_type) { case EXCP_HVC: @@ -50,7 +52,27 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type) return false; } - return true; + switch (param) { + case QEMU_PSCI_0_2_FN_PSCI_VERSION: + case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE: + case QEMU_PSCI_0_2_FN_AFFINITY_INFO: + case QEMU_PSCI_0_2_FN64_AFFINITY_INFO: + case QEMU_PSCI_0_2_FN_SYSTEM_RESET: + case QEMU_PSCI_0_2_FN_SYSTEM_OFF: + case QEMU_PSCI_0_1_FN_CPU_ON: + case QEMU_PSCI_0_2_FN_CPU_ON: + case QEMU_PSCI_0_2_FN64_CPU_ON: + case QEMU_PSCI_0_1_FN_CPU_OFF: + case QEMU_PSCI_0_2_FN_CPU_OFF: + case QEMU_PSCI_0_1_FN_CPU_SUSPEND: + case QEMU_PSCI_0_2_FN_CPU_SUSPEND: + case QEMU_PSCI_0_2_FN64_CPU_SUSPEND: + case QEMU_PSCI_0_1_FN_MIGRATE: + case QEMU_PSCI_0_2_FN_MIGRATE: + return true; + default: + return false; + } } void arm_handle_psci_call(ARMCPU *cpu) @@ -172,9 +194,10 @@ void arm_handle_psci_call(ARMCPU *cpu) break; case QEMU_PSCI_0_1_FN_MIGRATE: case QEMU_PSCI_0_2_FN_MIGRATE: - default: ret = QEMU_PSCI_RET_NOT_SUPPORTED; break; + default: + g_assert_not_reached(); } err: From cd6b1674d61120a77823b99516d27486c4f4f883 Mon Sep 17 00:00:00 2001 From: Kashyap Chamarthy Date: Fri, 19 Nov 2021 20:31:17 +0100 Subject: [PATCH 30/79] docs: Fix botched rST conversion of 'submitting-a-patch.rst' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I completely botched up the merged[0] rST conversion of this document by accidentally dropping entire hunks (!) of text. :-( I made it very hard for reviewers to spot it, as the omitted text was buried deep in the document. To fix my hatchet job, I reconverted the "SubmitAPatch" wiki[1] page from scratch and replaced the existing rST with it, while making sure I incorporated previous feedback. In summary, in this reconverted edition: - I did a careful (to the extent my eyes allowed) para-by-para comparison of the wiki and the rST to make sure I didn't omit anything accidentally. - I made sure to work in the cosmetic feedback[2] that Thomas Huth pointed out in the merged (and botched) edition: - fix the hyperlinks in "Split up long patches" - replace ".". with "does not end with a dot" (in "Write a meaningful commit message" section) - replace "---" with ``---`` so that it doesn't render as an em-dash (there were two other occurrences; I fixed those too) - Use "QEMU" spelling consistently in prose usage - Add a consistent "refer to git-config" link where appropriate Thanks to Thomas Huth and Alex Bennée for noticing it on IRC. And sorry for my sloppiness. Fixes: 9f73de8df033 ("docs: rSTify the "SubmitAPatch" wiki") [0] https://gitlab.com/qemu-project/qemu/-/commit/9f73de8df033 [1] https://wiki.qemu.org/index.php?title=Contribute/SubmitAPatch&oldid=10387 [2] https://lists.nongnu.org/archive/html/qemu-devel/2021-11/msg03600.html Signed-off-by: Kashyap Chamarthy Message-Id: <20211119193118.949698-2-kchamart@redhat.com> Reviewed-by: Eric Blake [thuth: Some more cosmetical changes, fixed links from external to internal] Signed-off-by: Thomas Huth --- docs/devel/stable-process.rst | 2 + docs/devel/style.rst | 2 + docs/devel/submitting-a-patch.rst | 198 +++++++++++++++++------ docs/devel/submitting-a-pull-request.rst | 9 +- docs/devel/trivial-patches.rst | 2 + 5 files changed, 161 insertions(+), 52 deletions(-) diff --git a/docs/devel/stable-process.rst b/docs/devel/stable-process.rst index e541b983fa..c21fb86645 100644 --- a/docs/devel/stable-process.rst +++ b/docs/devel/stable-process.rst @@ -1,3 +1,5 @@ +.. _stable-process: + QEMU and the stable process =========================== diff --git a/docs/devel/style.rst b/docs/devel/style.rst index e00af62e76..9c5c0fffd9 100644 --- a/docs/devel/style.rst +++ b/docs/devel/style.rst @@ -1,3 +1,5 @@ +.. _coding-style: + ================= QEMU Coding Style ================= diff --git a/docs/devel/submitting-a-patch.rst b/docs/devel/submitting-a-patch.rst index 6fefc67d52..6acded5c93 100644 --- a/docs/devel/submitting-a-patch.rst +++ b/docs/devel/submitting-a-patch.rst @@ -1,3 +1,5 @@ +.. _submitting-a-patch: + Submitting a Patch ================== @@ -20,11 +22,11 @@ one-shot fix, the bare minimum we ask is that: should not be posted on the bug tracker, posted on forums, or externally hosted and linked to. (We have other mailing lists too, but all patches must go to qemu-devel, possibly with a Cc: to another - list.) ``git send-email`` works best for delivering the patch without - mangling it (`hints for setting it - up `__), - but attachments can be used as a last resort on a first-time - submission. + list.) ``git send-email`` (`step-by-step setup + guide `__ and `hints and + tips `__) + works best for delivering the patch without mangling it, but + attachments can be used as a last resort on a first-time submission. - You must read replies to your message, and be willing to act on them. Note, however, that maintainers are often willing to manually fix up first-time contributions, since there is a learning curve involved in @@ -45,6 +47,8 @@ Reading the table of contents below should already give you an idea of the basic requirements. Use the table of contents as a reference, and read the parts that you have doubts about. +.. contents:: Table of Contents + .. _writing_your_patches: Writing your Patches @@ -60,11 +64,9 @@ check that you are in compliance with our coding standards. Be aware that ``checkpatch.pl`` is not infallible, though, especially where C preprocessor macros are involved; use some common sense too. See also: -- `QEMU Coding Style - `__ - +- :ref:`coding-style` - `Automate a checkpatch run on - commit `__ + commit `__ .. _base_patches_against_current_git_master: @@ -76,6 +78,13 @@ of QEMU because development will have moved on from then and it probably won't even apply to master. We only apply selected bugfixes to release branches and then only as backports once the code has gone into master. +It is also okay to base patches on top of other on-going work that is +not yet part of the git master branch. To aid continuous integration +tools, such as `patchew `__, you should `add a +tag `__ +line ``Based-on: $MESSAGE_ID`` to your cover letter to make the series +dependency obvious. + .. _split_up_long_patches: Split up long patches @@ -104,18 +113,17 @@ Make code motion patches easy to review If a series requires large blocks of code motion, there are tricks for making the refactoring easier to review. Split up the series so that semantic changes (or even function renames) are done in a separate patch -from the raw code motion. Use a one-time setup of -``git config diff.renames true; git config diff.algorithm patience`` -(Refer to `git-config `__.) The -``diff.renames`` property ensures file rename patches will be given in a -more compact representation that focuses only on the differences across -the file rename, instead of showing the entire old file as a deletion -and the new file as an insertion. Meanwhile, the 'diff.algorithm' -property ensures that extracting a non-contiguous subset of one file -into a new file, but where all extracted parts occur in the same order -both before and after the patch, will reduce churn in trying to treat -unrelated ``}`` lines in the original file as separating hunks of -changes. +from the raw code motion. Use a one-time setup of ``git config +diff.renames true;`` ``git config diff.algorithm patience`` (refer to +`git-config `__). The 'diff.renames' +property ensures file rename patches will be given in a more compact +representation that focuses only on the differences across the file +rename, instead of showing the entire old file as a deletion and the new +file as an insertion. Meanwhile, the 'diff.algorithm' property ensures +that extracting a non-contiguous subset of one file into a new file, but +where all extracted parts occur in the same order both before and after +the patch, will reduce churn in trying to treat unrelated ``}`` lines in +the original file as separating hunks of changes. Ideally, a code motion patch can be reviewed by doing:: @@ -138,8 +146,7 @@ as a separate patch which makes no semantic changes; don't put it in the same patch as your bug fix. For smaller patches in less frequently changed areas of QEMU, consider -using the `trivial patches process -`__. +using the :ref:`trivial-patches` process. .. _write_a_meaningful_commit_message: @@ -154,7 +161,7 @@ QEMU follows the usual standard for git commit messages: the first line (which becomes the email subject line) is "subsystem: single line summary of change". Whether the "single line summary of change" starts with a capital is a matter of taste, but we prefer that the summary does -not end in ".". Look at ``git shortlog -30`` for an idea of sample +not end in a dot. Look at ``git shortlog -30`` for an idea of sample subject lines. Then there is a blank line and a more detailed description of the patch, another blank and your Signed-off-by: line. Please do not use lines that are longer than 76 characters in your @@ -170,11 +177,75 @@ displays the subject line some distance apart (that is, a body that starts with "... so that" as a continuation of the subject line is harder to follow). +If your patch fixes a commit that is already in the repository, please +add an additional line with "Fixes: +("Fixed commit subject")" below the patch description / before your +"Signed-off-by:" line in the commit message. + +If your patch fixes a bug in the gitlab bug tracker, please add a line +with "Resolves: " to the commit message, too. Gitlab can +close bugs automatically once commits with the "Resolved:" keyword get +merged into the master branch of the project. And if your patch addresses +a bug in another public bug tracker, you can also use a line with +"Buglink: " for reference here, too. + +Example:: + + Fixes: 14055ce53c2d ("s390x/tcg: avoid overflows in time2tod/tod2time") + Resolves: https://gitlab.com/qemu-project/qemu/-/issues/42 + Buglink: https://bugs.launchpad.net/qemu/+bug/1804323`` + +.. _test_your_patches: + +Test your patches +~~~~~~~~~~~~~~~~~ + +Although QEMU has `continuous integration +services `__ that attempt to test +patches submitted to the list, it still saves everyone time if you have +already tested that your patch compiles and works. Because QEMU is such +a large project, it's okay to use configure arguments to limit what is +built for faster turnaround during your development time; but it is +still wise to also check that your patches work with a full build before +submitting a series, especially if your changes might have an unintended +effect on other areas of the code you don't normally experiment with. +See `Testing `__ for more details on what tests are available. +Also, it is a wise idea to include a testsuite addition as part of your +patches - either to ensure that future changes won't regress your new +feature, or to add a test which exposes the bug that the rest of your +series fixes. Keeping separate commits for the test and the fix allows +reviewers to rebase the test to occur first to prove it catches the +problem, then again to place it last in the series so that bisection +doesn't land on a known-broken state. + .. _submitting_your_patches: Submitting your Patches ----------------------- +.. _if_you_cannot_send_patch_emails: + +If you cannot send patch emails +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In rare cases it may not be possible to send properly formatted patch +emails. You can use `sourcehut `__ to send your +patches to the QEMU mailing list by following these steps: + +#. Register or sign in to your account +#. Add your SSH public key in `meta \| + keys `__. +#. Publish your git branch using **git push git@git.sr.ht:~USERNAME/qemu + HEAD** +#. Send your patches to the QEMU mailing list using the web-based + ``git-send-email`` UI at https://git.sr.ht/~USERNAME/qemu/send-email + +`This video +`__ +shows the web-based ``git-send-email`` workflow. Documentation is +available `here +`__. + .. _cc_the_relevant_maintainer: CC the relevant maintainer @@ -219,17 +290,26 @@ such as 'git-email' on Fedora-based systems.) Patch series need a cover letter, with shallow threading (all patches in the series are in-reply-to the cover letter, but not to each other); single unrelated patches do not need a cover letter (but if you do send a cover letter, -use --numbered so the cover and the patch have distinct subject lines). +use ``--numbered`` so the cover and the patch have distinct subject lines). Patches are easier to find if they start a new top-level thread, rather than being buried in-reply-to another existing thread. +.. _avoid_posting_large_binary_blob: + +Avoid posting large binary blob +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you added binaries to the repository, consider producing the patch +emails using ``git format-patch --no-binary`` and include a link to a +git repository to fetch the original commit. + .. _patch_emails_must_include_a_signed_off_by_line: Patch emails must include a ``Signed-off-by:`` line ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -For more information see `1.12) Sign your work -`__. +For more information see `SubmittingPatches 1.12 +`__. This is vital or we will not be able to apply your patch! Please use your real name to sign a patch (not an alias or acronym). @@ -246,8 +326,13 @@ that author's Signed-off-by: line is mandatory, with the same spelling. Include a meaningful cover letter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This usually applies only to a series that includes multiple patches; -the cover letter explains the overall goal of such a series. +This is a requirement for any series with multiple patches (as it aids +continuous integration), but optional for an isolated patch. The cover +letter explains the overall goal of such a series, and also provides a +convenient 0/N email for others to reply to the series as a whole. A +one-time setup of ``git config format.coverletter auto`` (refer to +`git-config `__) will generate the +cover letter as needed. When reviewers don't know your goal at the start of their review, they may object to early changes that don't make sense until the end of the @@ -288,6 +373,18 @@ it's best to: of the patchset you're looking for review on, and why reviewers should care +.. _consider_whether_your_patch_is_applicable_for_stable: + +Consider whether your patch is applicable for stable +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your patch fixes a severe issue or a regression, it may be applicable +for stable. In that case, consider adding ``Cc: qemu-stable@nongnu.org`` +to your patch to notify the stable maintainers. + +For more details on how QEMU's stable process works, refer to the +:ref:`stable-process` page. + .. _participating_in_code_review: Participating in Code Review @@ -367,19 +464,19 @@ Include version history in patchset revisions For later versions of patches, include a summary of changes from previous versions, but not in the commit message itself. In an email -formatted as a git patch, the commit message is the part above the "---" +formatted as a git patch, the commit message is the part above the ``---`` line, and this will go into the git changelog when the patch is committed. This part should be a self-contained description of what this version of the patch does, written to make sense to anybody who comes back to look at this commit in git in six months' time. The part below -the "---" line and above the patch proper (git format-patch puts the +the ``---`` line and above the patch proper (git format-patch puts the diffstat here) is a good place to put remarks for people reading the patch email, and this is where the "changes since previous version" -summary belongs. The -`git-publish `__ script can -help with tracking a good summary across versions. Also, the -`git-backport-diff `__ script -can help focus reviewers on what changed between revisions. +summary belongs. The `git-publish +`__ script can help with +tracking a good summary across versions. Also, the `git-backport-diff +`__ script can help focus +reviewers on what changed between revisions. .. _tips_and_tricks: @@ -411,27 +508,32 @@ If your patch seems to have been ignored If your patchset has received no replies you should "ping" it after a week or two, by sending an email as a reply-to-all to the patch mail, including the word "ping" and ideally also a link to the page for the -patch on -`patchwork `__ or -GMANE. It's worth double-checking for reasons why your patch might have -been ignored (forgot to CC the maintainer? annoyed people by failing to -respond to review comments on an earlier version?), but often for -less-maintained areas of QEMU patches do just slip through the cracks. -If your ping is also ignored, ping again after another week or so. As -the submitter, you are the person with the most motivation to get your -patch applied, so you have to be persistent. +patch on `patchew `__ or +`lore.kernel.org `__. It's worth +double-checking for reasons why your patch might have been ignored +(forgot to CC the maintainer? annoyed people by failing to respond to +review comments on an earlier version?), but often for less-maintained +areas of QEMU patches do just slip through the cracks. If your ping is +also ignored, ping again after another week or so. As the submitter, you +are the person with the most motivation to get your patch applied, so +you have to be persistent. .. _is_my_patch_in: Is my patch in? ~~~~~~~~~~~~~~~ +QEMU has some Continuous Integration machines that try to catch patch +submission problems as soon as possible. `patchew +`__ includes a web interface for tracking the +status of various threads that have been posted to the list, and may +send you an automated mail if it detected a problem with your patch. + Once your patch has had enough review on list, the maintainer for that area of code will send notification to the list that they are including your patch in a particular staging branch. Periodically, the maintainer -then sends a `pull request -`__ -for aggregating topic branches into mainline qemu. Generally, you do not +then takes care of :ref:`submitting-a-pull-request` +for aggregating topic branches into mainline QEMU. Generally, you do not need to send a pull request unless you have contributed enough patches to become a maintainer over a particular section of code. Maintainers may further modify your commit, by resolving simple merge conflicts or diff --git a/docs/devel/submitting-a-pull-request.rst b/docs/devel/submitting-a-pull-request.rst index 8729d29036..c9d1e8afd9 100644 --- a/docs/devel/submitting-a-pull-request.rst +++ b/docs/devel/submitting-a-pull-request.rst @@ -1,10 +1,11 @@ -Submit a Pull Request -===================== +.. _submitting-a-pull-request: + +Submitting a Pull Request +========================= QEMU welcomes contributions of code, but we generally expect these to be sent as simple patch emails to the mailing list (see our page on -`submitting a patch -`__ +:ref:`submitting-a-patch` for more details). Generally only existing submaintainers of a tree will need to submit pull requests, although occasionally for a large patch series we might ask a submitter to send a pull request. This page diff --git a/docs/devel/trivial-patches.rst b/docs/devel/trivial-patches.rst index db3f2001da..9380c730f7 100644 --- a/docs/devel/trivial-patches.rst +++ b/docs/devel/trivial-patches.rst @@ -1,3 +1,5 @@ +.. _trivial-patches: + Trivial Patches =============== From 93e86b1664951f02fceed9ac312576f60232d503 Mon Sep 17 00:00:00 2001 From: Kashyap Chamarthy Date: Fri, 19 Nov 2021 20:31:18 +0100 Subject: [PATCH 31/79] docs: List more commit-message tags in "submitting-a-patch" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add some more examples of commonly used commit-message tags. (Thanks: Alex Bennée) Signed-off-by: Kashyap Chamarthy Message-Id: <20211119193118.949698-3-kchamart@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Thomas Huth --- docs/devel/submitting-a-patch.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/devel/submitting-a-patch.rst b/docs/devel/submitting-a-patch.rst index 6acded5c93..e51259eb9c 100644 --- a/docs/devel/submitting-a-patch.rst +++ b/docs/devel/submitting-a-patch.rst @@ -195,6 +195,10 @@ Example:: Resolves: https://gitlab.com/qemu-project/qemu/-/issues/42 Buglink: https://bugs.launchpad.net/qemu/+bug/1804323`` +Some other tags that are used in commit messages include "Message-Id:" +"Tested-by:", "Acked-by:", "Reported-by:", "Suggested-by:". See ``git +log`` for these keywords for example usage. + .. _test_your_patches: Test your patches From b980c1aec63908074040e5cab135728e3b5db117 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Wed, 17 Nov 2021 22:07:02 +0100 Subject: [PATCH 32/79] Fix some typos in documentation (found by codespell) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Weil Message-Id: <20211117210702.1393570-1-sw@weilnetz.de> Reviewed-by: Philippe Mathieu-Daudé [thuth: "what's" --> "what is" as suggested by philmd] Signed-off-by: Thomas Huth --- docs/devel/multi-process.rst | 2 +- docs/devel/qgraph.rst | 2 +- docs/devel/writing-monitor-commands.rst | 2 +- docs/hyperv.txt | 2 +- docs/system/cpu-models-x86.rst.inc | 2 +- docs/system/devices/nvme.rst | 2 +- docs/system/gdb.rst | 2 +- docs/system/ppc/ppce500.rst | 2 +- docs/system/riscv/shakti-c.rst | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/devel/multi-process.rst b/docs/devel/multi-process.rst index e5758a79ab..5c857ff3b9 100644 --- a/docs/devel/multi-process.rst +++ b/docs/devel/multi-process.rst @@ -641,7 +641,7 @@ the CPU that issued the MMIO. +==========+========================+ | rid | range MMIO is within | +----------+------------------------+ -| offset | offset withing *rid* | +| offset | offset within *rid* | +----------+------------------------+ | type | e.g., load or store | +----------+------------------------+ diff --git a/docs/devel/qgraph.rst b/docs/devel/qgraph.rst index db44d71002..43342d9d65 100644 --- a/docs/devel/qgraph.rst +++ b/docs/devel/qgraph.rst @@ -14,7 +14,7 @@ support that device. Using only libqos APIs, the test has to manually take care of covering all the setups, and build the correct command line. -This also introduces backward compability issues: if a device/driver command +This also introduces backward compatibility issues: if a device/driver command line name is changed, all tests that use that will not work properly anymore and need to be adjusted. diff --git a/docs/devel/writing-monitor-commands.rst b/docs/devel/writing-monitor-commands.rst index b3e2c8481d..1693822f8f 100644 --- a/docs/devel/writing-monitor-commands.rst +++ b/docs/devel/writing-monitor-commands.rst @@ -677,7 +677,7 @@ return a single text string:: The ``HumanReadableText`` struct is intended to be used for all commands, under the ``x-`` name prefix that are returning unstructured -text targetted at humans. It should never be used for commands outside +text targeted at humans. It should never be used for commands outside the ``x-`` name prefix, as those should be using structured QAPI types. Implementing the QMP command diff --git a/docs/hyperv.txt b/docs/hyperv.txt index 5d99fd9a72..0417c183a3 100644 --- a/docs/hyperv.txt +++ b/docs/hyperv.txt @@ -195,7 +195,7 @@ The enlightenment allows to use Hyper-V SynIC with hardware APICv/AVIC enabled. Normally, Hyper-V SynIC disables these hardware feature and suggests the guest to use paravirtualized AutoEOI feature. Note: enabling this feature on old hardware (without APICv/AVIC support) may -have negative effect on guest's performace. +have negative effect on guest's performance. 3.19. hv-no-nonarch-coresharing=on/off/auto =========================================== diff --git a/docs/system/cpu-models-x86.rst.inc b/docs/system/cpu-models-x86.rst.inc index 6e8be7d79b..7f6368f999 100644 --- a/docs/system/cpu-models-x86.rst.inc +++ b/docs/system/cpu-models-x86.rst.inc @@ -49,7 +49,7 @@ future OS and toolchains are likely to target newer ABIs. The table that follows illustrates which ABI compatibility levels can be satisfied by the QEMU CPU models. Note that the table only lists the long term stable CPU model versions (eg Haswell-v4). -In addition to whats listed, there are also many CPU model +In addition to what is listed, there are also many CPU model aliases which resolve to a different CPU model version, depending on the machine type is in use. diff --git a/docs/system/devices/nvme.rst b/docs/system/devices/nvme.rst index a1c0db01f6..b5acb2a9c1 100644 --- a/docs/system/devices/nvme.rst +++ b/docs/system/devices/nvme.rst @@ -70,7 +70,7 @@ namespaces and additional features, the ``nvme-ns`` device must be used. The namespaces defined by the ``nvme-ns`` device will attach to the most recently defined ``nvme-bus`` that is created by the ``nvme`` device. Namespace -identifers are allocated automatically, starting from ``1``. +identifiers are allocated automatically, starting from ``1``. There are a number of parameters available: diff --git a/docs/system/gdb.rst b/docs/system/gdb.rst index bdb42dae2f..453eb73f6c 100644 --- a/docs/system/gdb.rst +++ b/docs/system/gdb.rst @@ -56,7 +56,7 @@ machine has more than one CPU, QEMU exposes each CPU cluster as a separate "inferior", where each CPU within the cluster is a separate "thread". Most QEMU machine types have identical CPUs, so there is a single cluster which has all the CPUs in it. A few machine types are -heterogenous and have multiple clusters: for example the ``sifive_u`` +heterogeneous and have multiple clusters: for example the ``sifive_u`` machine has a cluster with one E51 core and a second cluster with four U54 cores. Here the E51 is the only thread in the first inferior, and the U54 cores are all threads in the second inferior. diff --git a/docs/system/ppc/ppce500.rst b/docs/system/ppc/ppce500.rst index afc58f60f5..9beef39171 100644 --- a/docs/system/ppc/ppce500.rst +++ b/docs/system/ppc/ppce500.rst @@ -75,7 +75,7 @@ as the BIOS. QEMU follows below truth table to select which payload to execute: When both -bios and -kernel are present, QEMU loads U-Boot and U-Boot in turns automatically loads the kernel image specified by the -kernel parameter via U-Boot's built-in "bootm" command, hence a legacy uImage format is required in -such senario. +such scenario. Running Linux kernel -------------------- diff --git a/docs/system/riscv/shakti-c.rst b/docs/system/riscv/shakti-c.rst index a6035d42b0..fea57f7b6b 100644 --- a/docs/system/riscv/shakti-c.rst +++ b/docs/system/riscv/shakti-c.rst @@ -45,7 +45,7 @@ Shakti SDK can be used to generate the baremetal example UART applications. Binary would be generated in: software/examples/uart_applns/loopback/output/loopback.shakti -You could also download the precompiled example applicatons using below +You could also download the precompiled example applications using below commands. .. code-block:: bash From 8f75cae2dda8a55eb3a6c712bd22b18a90c0a5ac Mon Sep 17 00:00:00 2001 From: "Rao, Lei" Date: Mon, 22 Nov 2021 15:49:46 +0800 Subject: [PATCH 33/79] docs: Drop deprecated 'props' from object-add In commit 5024340745 "qapi/qom: Drop deprecated 'props' from object-add" (v6.0.0), we also should update documents. Signed-off-by: Lei Rao Message-Id: <1637567387-28250-1-git-send-email-lei.rao@intel.com> Reviewed-by: Markus Armbruster Signed-off-by: Thomas Huth --- docs/COLO-FT.txt | 16 ++++++++-------- docs/system/authz.rst | 26 ++++++++++---------------- docs/throttle.txt | 8 +++----- docs/tools/qemu-nbd.rst | 2 +- 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/docs/COLO-FT.txt b/docs/COLO-FT.txt index 8d6d53a5a2..fd5ffcc6e5 100644 --- a/docs/COLO-FT.txt +++ b/docs/COLO-FT.txt @@ -289,11 +289,11 @@ Wait until disk is synced, then: {'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0'}} {'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'node': 'replication0' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'props': { 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'props': { 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'props': { 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } {'execute': 'object-add', 'arguments':{ 'qom-type': 'iothread', 'id': 'iothread1' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'props': { 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } {'execute': 'migrate-set-capabilities', 'arguments':{ 'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } {'execute': 'migrate', 'arguments':{ 'uri': 'tcp:127.0.0.2:9998' } } @@ -318,11 +318,11 @@ Wait until disk is synced, then: {'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.1,file.port=9999,file.export=parent0,node-name=replication0'}} {'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'node': 'replication0' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } {'execute': 'object-add', 'arguments':{ 'qom-type': 'iothread', 'id': 'iothread1' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'props': { 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } {'execute': 'migrate-set-capabilities', 'arguments':{ 'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } {'execute': 'migrate', 'arguments':{ 'uri': 'tcp:127.0.0.1:9998' } } diff --git a/docs/system/authz.rst b/docs/system/authz.rst index 942af39602..55b7315e49 100644 --- a/docs/system/authz.rst +++ b/docs/system/authz.rst @@ -77,9 +77,7 @@ To create an instance of this driver via QMP: "arguments": { "qom-type": "authz-simple", "id": "authz0", - "props": { - "identity": "fred" - } + "identity": "fred" } } @@ -110,15 +108,13 @@ To create an instance of this class via QMP: "arguments": { "qom-type": "authz-list", "id": "authz0", - "props": { - "rules": [ - { "match": "fred", "policy": "allow", "format": "exact" }, - { "match": "bob", "policy": "allow", "format": "exact" }, - { "match": "danb", "policy": "deny", "format": "exact" }, - { "match": "dan*", "policy": "allow", "format": "glob" } - ], - "policy": "deny" - } + "rules": [ + { "match": "fred", "policy": "allow", "format": "exact" }, + { "match": "bob", "policy": "allow", "format": "exact" }, + { "match": "danb", "policy": "deny", "format": "exact" }, + { "match": "dan*", "policy": "allow", "format": "glob" } + ], + "policy": "deny" } } @@ -143,10 +139,8 @@ To create an instance of this class via QMP: "arguments": { "qom-type": "authz-list-file", "id": "authz0", - "props": { - "filename": "/etc/qemu/myvm-vnc.acl", - "refresh": true - } + "filename": "/etc/qemu/myvm-vnc.acl", + "refresh": true } } diff --git a/docs/throttle.txt b/docs/throttle.txt index b5b78b7326..0a0453a5ee 100644 --- a/docs/throttle.txt +++ b/docs/throttle.txt @@ -273,11 +273,9 @@ A group can be created using the object-add QMP function: "arguments": { "qom-type": "throttle-group", "id": "group0", - "props": { - "limits" : { - "iops-total": 1000 - "bps-write": 2097152 - } + "limits" : { + "iops-total": 1000, + "bps-write": 2097152 } } } diff --git a/docs/tools/qemu-nbd.rst b/docs/tools/qemu-nbd.rst index 56e54cd441..726cd18960 100644 --- a/docs/tools/qemu-nbd.rst +++ b/docs/tools/qemu-nbd.rst @@ -31,7 +31,7 @@ driver options if ``--image-opts`` is specified. *dev* is an NBD device. -.. option:: --object type,id=ID,...props... +.. option:: --object type,id=ID,... Define a new instance of the *type* object class identified by *ID*. See the :manpage:`qemu(1)` manual page for full details of the properties From eff708a876b40fe71bedb792d084972d7a52166a Mon Sep 17 00:00:00 2001 From: "Rao, Lei" Date: Mon, 22 Nov 2021 15:49:47 +0800 Subject: [PATCH 34/79] docs: Use double quotes instead of single quotes for COLO Signed-off-by: Lei Rao Message-Id: <1637567387-28250-2-git-send-email-lei.rao@intel.com> Reviewed-by: Markus Armbruster Signed-off-by: Thomas Huth --- docs/COLO-FT.txt | 106 ++++++++++++++++++------------------- docs/block-replication.txt | 52 +++++++++--------- 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/docs/COLO-FT.txt b/docs/COLO-FT.txt index fd5ffcc6e5..8ec653f81c 100644 --- a/docs/COLO-FT.txt +++ b/docs/COLO-FT.txt @@ -209,9 +209,9 @@ children.0=childs0 \ 3. On Secondary VM's QEMU monitor, issue command -{'execute':'qmp_capabilities'} -{'execute': 'nbd-server-start', 'arguments': {'addr': {'type': 'inet', 'data': {'host': '0.0.0.0', 'port': '9999'} } } } -{'execute': 'nbd-server-add', 'arguments': {'device': 'parent0', 'writable': true } } +{"execute":"qmp_capabilities"} +{"execute": "nbd-server-start", "arguments": {"addr": {"type": "inet", "data": {"host": "0.0.0.0", "port": "9999"} } } } +{"execute": "nbd-server-add", "arguments": {"device": "parent0", "writable": true } } Note: a. The qmp command nbd-server-start and nbd-server-add must be run @@ -222,11 +222,11 @@ Note: will be merged into the parent disk on failover. 4. On Primary VM's QEMU monitor, issue command: -{'execute':'qmp_capabilities'} -{'execute': 'human-monitor-command', 'arguments': {'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0'}} -{'execute': 'x-blockdev-change', 'arguments':{'parent': 'colo-disk0', 'node': 'replication0' } } -{'execute': 'migrate-set-capabilities', 'arguments': {'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } -{'execute': 'migrate', 'arguments': {'uri': 'tcp:127.0.0.2:9998' } } +{"execute":"qmp_capabilities"} +{"execute": "human-monitor-command", "arguments": {"command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0"}} +{"execute": "x-blockdev-change", "arguments":{"parent": "colo-disk0", "node": "replication0" } } +{"execute": "migrate-set-capabilities", "arguments": {"capabilities": [ {"capability": "x-colo", "state": true } ] } } +{"execute": "migrate", "arguments": {"uri": "tcp:127.0.0.2:9998" } } Note: a. There should be only one NBD Client for each primary disk. @@ -249,59 +249,59 @@ if you want to resume the replication, follow "Secondary resume replication" == Primary Failover == The Secondary died, resume on the Primary -{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'child': 'children.1'} } -{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_del replication0' } } -{'execute': 'object-del', 'arguments':{ 'id': 'comp0' } } -{'execute': 'object-del', 'arguments':{ 'id': 'iothread1' } } -{'execute': 'object-del', 'arguments':{ 'id': 'm0' } } -{'execute': 'object-del', 'arguments':{ 'id': 'redire0' } } -{'execute': 'object-del', 'arguments':{ 'id': 'redire1' } } -{'execute': 'x-colo-lost-heartbeat' } +{"execute": "x-blockdev-change", "arguments":{ "parent": "colo-disk0", "child": "children.1"} } +{"execute": "human-monitor-command", "arguments":{ "command-line": "drive_del replication0" } } +{"execute": "object-del", "arguments":{ "id": "comp0" } } +{"execute": "object-del", "arguments":{ "id": "iothread1" } } +{"execute": "object-del", "arguments":{ "id": "m0" } } +{"execute": "object-del", "arguments":{ "id": "redire0" } } +{"execute": "object-del", "arguments":{ "id": "redire1" } } +{"execute": "x-colo-lost-heartbeat" } == Secondary Failover == The Primary died, resume on the Secondary and prepare to become the new Primary -{'execute': 'nbd-server-stop'} -{'execute': 'x-colo-lost-heartbeat'} +{"execute": "nbd-server-stop"} +{"execute": "x-colo-lost-heartbeat"} -{'execute': 'object-del', 'arguments':{ 'id': 'f2' } } -{'execute': 'object-del', 'arguments':{ 'id': 'f1' } } -{'execute': 'chardev-remove', 'arguments':{ 'id': 'red1' } } -{'execute': 'chardev-remove', 'arguments':{ 'id': 'red0' } } +{"execute": "object-del", "arguments":{ "id": "f2" } } +{"execute": "object-del", "arguments":{ "id": "f1" } } +{"execute": "chardev-remove", "arguments":{ "id": "red1" } } +{"execute": "chardev-remove", "arguments":{ "id": "red0" } } -{'execute': 'chardev-add', 'arguments':{ 'id': 'mirror0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '0.0.0.0', 'port': '9003' } }, 'server': true } } } } -{'execute': 'chardev-add', 'arguments':{ 'id': 'compare1', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '0.0.0.0', 'port': '9004' } }, 'server': true } } } } -{'execute': 'chardev-add', 'arguments':{ 'id': 'compare0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9001' } }, 'server': true } } } } -{'execute': 'chardev-add', 'arguments':{ 'id': 'compare0-0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9001' } }, 'server': false } } } } -{'execute': 'chardev-add', 'arguments':{ 'id': 'compare_out', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9005' } }, 'server': true } } } } -{'execute': 'chardev-add', 'arguments':{ 'id': 'compare_out0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9005' } }, 'server': false } } } } +{"execute": "chardev-add", "arguments":{ "id": "mirror0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "0.0.0.0", "port": "9003" } }, "server": true } } } } +{"execute": "chardev-add", "arguments":{ "id": "compare1", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "0.0.0.0", "port": "9004" } }, "server": true } } } } +{"execute": "chardev-add", "arguments":{ "id": "compare0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9001" } }, "server": true } } } } +{"execute": "chardev-add", "arguments":{ "id": "compare0-0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9001" } }, "server": false } } } } +{"execute": "chardev-add", "arguments":{ "id": "compare_out", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9005" } }, "server": true } } } } +{"execute": "chardev-add", "arguments":{ "id": "compare_out0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9005" } }, "server": false } } } } == Primary resume replication == Resume replication after new Secondary is up. Start the new Secondary (Steps 2 and 3 above), then on the Primary: -{'execute': 'drive-mirror', 'arguments':{ 'device': 'colo-disk0', 'job-id': 'resync', 'target': 'nbd://127.0.0.2:9999/parent0', 'mode': 'existing', 'format': 'raw', 'sync': 'full'} } +{"execute": "drive-mirror", "arguments":{ "device": "colo-disk0", "job-id": "resync", "target": "nbd://127.0.0.2:9999/parent0", "mode": "existing", "format": "raw", "sync": "full"} } Wait until disk is synced, then: -{'execute': 'stop'} -{'execute': 'block-job-cancel', 'arguments':{ 'device': 'resync'} } +{"execute": "stop"} +{"execute": "block-job-cancel", "arguments":{ "device": "resync"} } -{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0'}} -{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'node': 'replication0' } } +{"execute": "human-monitor-command", "arguments":{ "command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0"}} +{"execute": "x-blockdev-change", "arguments":{ "parent": "colo-disk0", "node": "replication0" } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'iothread', 'id': 'iothread1' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } +{"execute": "object-add", "arguments":{ "qom-type": "filter-mirror", "id": "m0", "netdev": "hn0", "queue": "tx", "outdev": "mirror0" } } +{"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire0", "netdev": "hn0", "queue": "rx", "indev": "compare_out" } } +{"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire1", "netdev": "hn0", "queue": "rx", "outdev": "compare0" } } +{"execute": "object-add", "arguments":{ "qom-type": "iothread", "id": "iothread1" } } +{"execute": "object-add", "arguments":{ "qom-type": "colo-compare", "id": "comp0", "primary_in": "compare0-0", "secondary_in": "compare1", "outdev": "compare_out0", "iothread": "iothread1" } } -{'execute': 'migrate-set-capabilities', 'arguments':{ 'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } -{'execute': 'migrate', 'arguments':{ 'uri': 'tcp:127.0.0.2:9998' } } +{"execute": "migrate-set-capabilities", "arguments":{ "capabilities": [ {"capability": "x-colo", "state": true } ] } } +{"execute": "migrate", "arguments":{ "uri": "tcp:127.0.0.2:9998" } } Note: If this Primary previously was a Secondary, then we need to insert the filters before the filter-rewriter by using the -"'insert': 'before', 'position': 'id=rew0'" Options. See below. +""insert": "before", "position": "id=rew0"" Options. See below. == Secondary resume replication == Become Primary and resume replication after new Secondary is up. Note @@ -309,23 +309,23 @@ that now 127.0.0.1 is the Secondary and 127.0.0.2 is the Primary. Start the new Secondary (Steps 2 and 3 above, but with primary_ip=127.0.0.2), then on the old Secondary: -{'execute': 'drive-mirror', 'arguments':{ 'device': 'colo-disk0', 'job-id': 'resync', 'target': 'nbd://127.0.0.1:9999/parent0', 'mode': 'existing', 'format': 'raw', 'sync': 'full'} } +{"execute": "drive-mirror", "arguments":{ "device": "colo-disk0", "job-id": "resync", "target": "nbd://127.0.0.1:9999/parent0", "mode": "existing", "format": "raw", "sync": "full"} } Wait until disk is synced, then: -{'execute': 'stop'} -{'execute': 'block-job-cancel', 'arguments':{ 'device': 'resync' } } +{"execute": "stop"} +{"execute": "block-job-cancel", "arguments":{ "device": "resync" } } -{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.1,file.port=9999,file.export=parent0,node-name=replication0'}} -{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'node': 'replication0' } } +{"execute": "human-monitor-command", "arguments":{ "command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.1,file.port=9999,file.export=parent0,node-name=replication0"}} +{"execute": "x-blockdev-change", "arguments":{ "parent": "colo-disk0", "node": "replication0" } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'iothread', 'id': 'iothread1' } } -{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } +{"execute": "object-add", "arguments":{ "qom-type": "filter-mirror", "id": "m0", "insert": "before", "position": "id=rew0", "netdev": "hn0", "queue": "tx", "outdev": "mirror0" } } +{"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire0", "insert": "before", "position": "id=rew0", "netdev": "hn0", "queue": "rx", "indev": "compare_out" } } +{"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire1", "insert": "before", "position": "id=rew0", "netdev": "hn0", "queue": "rx", "outdev": "compare0" } } +{"execute": "object-add", "arguments":{ "qom-type": "iothread", "id": "iothread1" } } +{"execute": "object-add", "arguments":{ "qom-type": "colo-compare", "id": "comp0", "primary_in": "compare0-0", "secondary_in": "compare1", "outdev": "compare_out0", "iothread": "iothread1" } } -{'execute': 'migrate-set-capabilities', 'arguments':{ 'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } -{'execute': 'migrate', 'arguments':{ 'uri': 'tcp:127.0.0.1:9998' } } +{"execute": "migrate-set-capabilities", "arguments":{ "capabilities": [ {"capability": "x-colo", "state": true } ] } } +{"execute": "migrate", "arguments":{ "uri": "tcp:127.0.0.1:9998" } } == TODO == 1. Support shared storage. diff --git a/docs/block-replication.txt b/docs/block-replication.txt index 59eb2b33b3..b0f23761c6 100644 --- a/docs/block-replication.txt +++ b/docs/block-replication.txt @@ -156,15 +156,15 @@ Primary: children.0.driver=raw Run qmp command in primary qemu: - { 'execute': 'human-monitor-command', - 'arguments': { - 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=xxxx,file.port=xxxx,file.export=colo1,node-name=nbd_client1' + { "execute": "human-monitor-command", + "arguments": { + "command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=xxxx,file.port=xxxx,file.export=colo1,node-name=nbd_client1" } } - { 'execute': 'x-blockdev-change', - 'arguments': { - 'parent': 'colo1', - 'node': 'nbd_client1' + { "execute": "x-blockdev-change", + "arguments": { + "parent": "colo1", + "node": "nbd_client1" } } Note: @@ -189,21 +189,21 @@ Secondary: vote-threshold=1,children.0=childs1 Then run qmp command in secondary qemu: - { 'execute': 'nbd-server-start', - 'arguments': { - 'addr': { - 'type': 'inet', - 'data': { - 'host': 'xxx', - 'port': 'xxx' + { "execute": "nbd-server-start", + "arguments": { + "addr": { + "type": "inet", + "data": { + "host": "xxx", + "port": "xxx" } } } } - { 'execute': 'nbd-server-add', - 'arguments': { - 'device': 'colo1', - 'writable': true + { "execute": "nbd-server-add", + "arguments": { + "device": "colo1", + "writable": true } } @@ -223,22 +223,22 @@ After Failover: Primary: The secondary host is down, so we should run the following qmp command to remove the nbd child from the quorum: - { 'execute': 'x-blockdev-change', - 'arguments': { - 'parent': 'colo1', - 'child': 'children.1' + { "execute": "x-blockdev-change", + "arguments": { + "parent": "colo1", + "child": "children.1" } } - { 'execute': 'human-monitor-command', - 'arguments': { - 'command-line': 'drive_del xxxx' + { "execute": "human-monitor-command", + "arguments": { + "command-line": "drive_del xxxx" } } Note: there is no qmp command to remove the blockdev now Secondary: The primary host is down, so we should do the following thing: - { 'execute': 'nbd-server-stop' } + { "execute": "nbd-server-stop" } Promote Secondary to Primary: see COLO-FT.txt From c5ba62195427d65a44472901cff3dddffc14b3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 18 Nov 2021 20:27:44 +0100 Subject: [PATCH 35/79] docs: Render binary names as monospaced text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20211118192744.64325-1-philmd@redhat.com> Reviewed-by: Darren Kenny Signed-off-by: Thomas Huth --- docs/about/removed-features.rst | 8 ++++---- docs/devel/build-system.rst | 6 +++--- docs/devel/multi-process.rst | 6 +++--- docs/devel/testing.rst | 8 ++++---- docs/image-fuzzer.txt | 6 +++--- docs/system/arm/orangepi.rst | 2 +- docs/system/images.rst | 2 +- docs/system/qemu-block-drivers.rst.inc | 6 +++--- docs/system/tls.rst | 2 +- docs/tools/qemu-img.rst | 18 +++++++++--------- docs/tools/qemu-nbd.rst | 4 ++-- docs/tools/qemu-storage-daemon.rst | 7 ++++--- docs/tools/virtiofsd.rst | 4 ++-- 13 files changed, 40 insertions(+), 39 deletions(-) diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst index 9d0d90c90d..d42c3341de 100644 --- a/docs/about/removed-features.rst +++ b/docs/about/removed-features.rst @@ -658,8 +658,8 @@ enforce that any failure to open the backing image (including if the backing file is missing or an incorrect format was specified) is an error when ``-u`` is not used. -qemu-img amend to adjust backing file (removed in 6.1) -'''''''''''''''''''''''''''''''''''''''''''''''''''''' +``qemu-img amend`` to adjust backing file (removed in 6.1) +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''' The use of ``qemu-img amend`` to modify the name or format of a qcow2 backing image was never fully documented or tested, and interferes @@ -670,8 +670,8 @@ backing chain should be performed with ``qemu-img rebase -u`` either before or after the remaining changes being performed by amend, as appropriate. -qemu-img backing file without format (removed in 6.1) -''''''''''''''''''''''''''''''''''''''''''''''''''''' +``qemu-img`` backing file without format (removed in 6.1) +''''''''''''''''''''''''''''''''''''''''''''''''''''''''' The use of ``qemu-img create``, ``qemu-img rebase``, or ``qemu-img convert`` to create or modify an image that depends on a backing file diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst index 7a83f5fc0d..431caba7aa 100644 --- a/docs/devel/build-system.rst +++ b/docs/devel/build-system.rst @@ -121,11 +121,11 @@ process for: 1) executables, which include: - - Tools - qemu-img, qemu-nbd, qga (guest agent), etc + - Tools - ``qemu-img``, ``qemu-nbd``, ``qga`` (guest agent), etc - - System emulators - qemu-system-$ARCH + - System emulators - ``qemu-system-$ARCH`` - - Userspace emulators - qemu-$ARCH + - Userspace emulators - ``qemu-$ARCH`` - Unit tests diff --git a/docs/devel/multi-process.rst b/docs/devel/multi-process.rst index 5c857ff3b9..e4801751f2 100644 --- a/docs/devel/multi-process.rst +++ b/docs/devel/multi-process.rst @@ -187,9 +187,9 @@ desired, in which the emulation application should only be allowed to access the files or devices the VM it's running on behalf of can access. #### qemu-io model -Qemu-io is a test harness used to test changes to the QEMU block backend -object code. (e.g., the code that implements disk images for disk driver -emulation) Qemu-io is not a device emulation application per se, but it +``qemu-io`` is a test harness used to test changes to the QEMU block backend +object code (e.g., the code that implements disk images for disk driver +emulation). ``qemu-io`` is not a device emulation application per se, but it does compile the QEMU block objects into a separate binary from the main QEMU one. This could be useful for disk device emulation, since its emulation applications will need to include the QEMU block objects. diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst index 60c59023e5..755343c7dd 100644 --- a/docs/devel/testing.rst +++ b/docs/devel/testing.rst @@ -564,11 +564,11 @@ exploiting a QEMU security bug to compromise the host. QEMU binaries ~~~~~~~~~~~~~ -By default, qemu-system-x86_64 is searched in $PATH to run the guest. If there -isn't one, or if it is older than 2.10, the test won't work. In this case, +By default, ``qemu-system-x86_64`` is searched in $PATH to run the guest. If +there isn't one, or if it is older than 2.10, the test won't work. In this case, provide the QEMU binary in env var: ``QEMU=/path/to/qemu-2.10+``. -Likewise the path to qemu-img can be set in QEMU_IMG environment variable. +Likewise the path to ``qemu-img`` can be set in QEMU_IMG environment variable. Make jobs ~~~~~~~~~ @@ -650,7 +650,7 @@ supported. To start the fuzzer, run tests/image-fuzzer/runner.py -c '[["qemu-img", "info", "$test_img"]]' /tmp/test qcow2 -Alternatively, some command different from "qemu-img info" can be tested, by +Alternatively, some command different from ``qemu-img info`` can be tested, by changing the ``-c`` option. Integration tests using the Avocado Framework diff --git a/docs/image-fuzzer.txt b/docs/image-fuzzer.txt index 3e23ebec33..279cc8c807 100644 --- a/docs/image-fuzzer.txt +++ b/docs/image-fuzzer.txt @@ -51,10 +51,10 @@ assumes that core dumps will be generated in the current working directory. For comprehensive test results, please, set up your test environment properly. -Paths to binaries under test (SUTs) qemu-img and qemu-io are retrieved from -environment variables. If the environment check fails the runner will +Paths to binaries under test (SUTs) ``qemu-img`` and ``qemu-io`` are retrieved +from environment variables. If the environment check fails the runner will use SUTs installed in system paths. -qemu-img is required for creation of backing files, so it's mandatory to set +``qemu-img`` is required for creation of backing files, so it's mandatory to set the related environment variable if it's not installed in the system path. For details about environment variables see qemu-iotests/check. diff --git a/docs/system/arm/orangepi.rst b/docs/system/arm/orangepi.rst index c55694dd91..83c7445197 100644 --- a/docs/system/arm/orangepi.rst +++ b/docs/system/arm/orangepi.rst @@ -128,7 +128,7 @@ Alternatively, you can also choose to build you own image with buildroot using the orangepi_pc_defconfig. Also see https://buildroot.org for more information. When using an image as an SD card, it must be resized to a power of two. This can be -done with the qemu-img command. It is recommended to only increase the image size +done with the ``qemu-img`` command. It is recommended to only increase the image size instead of shrinking it to a power of two, to avoid loss of data. For example, to prepare a downloaded Armbian image, first extract it and then increase its size to one gigabyte as follows: diff --git a/docs/system/images.rst b/docs/system/images.rst index 3d9144e625..d000bd6b6f 100644 --- a/docs/system/images.rst +++ b/docs/system/images.rst @@ -20,7 +20,7 @@ where myimage.img is the disk image filename and mysize is its size in kilobytes. You can add an ``M`` suffix to give the size in megabytes and a ``G`` suffix for gigabytes. -See the qemu-img invocation documentation for more information. +See the ``qemu-img`` invocation documentation for more information. .. _disk_005fimages_005fsnapshot_005fmode: diff --git a/docs/system/qemu-block-drivers.rst.inc b/docs/system/qemu-block-drivers.rst.inc index 16225710eb..e313784426 100644 --- a/docs/system/qemu-block-drivers.rst.inc +++ b/docs/system/qemu-block-drivers.rst.inc @@ -511,13 +511,13 @@ of an inet socket: |qemu_system| linux.img -hdb nbd+unix://?socket=/tmp/my_socket -In this case, the block device must be exported using qemu-nbd: +In this case, the block device must be exported using ``qemu-nbd``: .. parsed-literal:: qemu-nbd --socket=/tmp/my_socket my_disk.qcow2 -The use of qemu-nbd allows sharing of a disk between several guests: +The use of ``qemu-nbd`` allows sharing of a disk between several guests: .. parsed-literal:: @@ -530,7 +530,7 @@ and then you can use it with two guests: |qemu_system| linux1.img -hdb nbd+unix://?socket=/tmp/my_socket |qemu_system| linux2.img -hdb nbd+unix://?socket=/tmp/my_socket -If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's +If the ``nbd-server`` uses named exports (supported since NBD 2.9.18, or with QEMU's own embedded NBD server), you must specify an export name in the URI: .. parsed-literal:: diff --git a/docs/system/tls.rst b/docs/system/tls.rst index b0973afe1b..1a04674362 100644 --- a/docs/system/tls.rst +++ b/docs/system/tls.rst @@ -311,7 +311,7 @@ containing one or more usernames and random keys:: mkdir -m 0700 /tmp/keys psktool -u rich -p /tmp/keys/keys.psk -TLS-enabled servers such as qemu-nbd can use this directory like so:: +TLS-enabled servers such as ``qemu-nbd`` can use this directory like so:: qemu-nbd \ -t -x / \ diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst index c0a4443146..d663dd92bd 100644 --- a/docs/tools/qemu-img.rst +++ b/docs/tools/qemu-img.rst @@ -127,9 +127,9 @@ by the used format or see the format descriptions below for details. .. option:: -S SIZE Indicates the consecutive number of bytes that must contain only zeros - for qemu-img to create a sparse image during conversion. This value is rounded - down to the nearest 512 bytes. You may use the common size suffixes like - ``k`` for kilobytes. + for ``qemu-img`` to create a sparse image during conversion. This value is + rounded down to the nearest 512 bytes. You may use the common size suffixes + like ``k`` for kilobytes. .. option:: -t CACHE @@ -431,7 +431,7 @@ Command description: suppressed from the destination image. *SPARSE_SIZE* indicates the consecutive number of bytes (defaults to 4k) - that must contain only zeros for qemu-img to create a sparse image during + that must contain only zeros for ``qemu-img`` to create a sparse image during conversion. If *SPARSE_SIZE* is 0, the source will not be scanned for unallocated or zero sectors, and the destination image will always be fully allocated. @@ -447,7 +447,7 @@ Command description: If the ``-n`` option is specified, the target volume creation will be skipped. This is useful for formats such as ``rbd`` if the target volume has already been created with site specific options that cannot - be supplied through qemu-img. + be supplied through ``qemu-img``. Out of order writes can be enabled with ``-W`` to improve performance. This is only recommended for preallocated devices like host devices or other @@ -472,7 +472,7 @@ Command description: If the option *BACKING_FILE* is specified, then the image will record only the differences from *BACKING_FILE*. No size needs to be specified in this case. *BACKING_FILE* will never be modified unless you use the - ``commit`` monitor command (or qemu-img commit). + ``commit`` monitor command (or ``qemu-img commit``). If a relative path name is given, the backing file is looked up relative to the directory containing *FILENAME*. @@ -684,7 +684,7 @@ Command description: Safe mode This is the default mode and performs a real rebase operation. The - new backing file may differ from the old one and qemu-img rebase + new backing file may differ from the old one and ``qemu-img rebase`` will take care of keeping the guest-visible content of *FILENAME* unchanged. @@ -697,7 +697,7 @@ Command description: exists. Unsafe mode - qemu-img uses the unsafe mode if ``-u`` is specified. In this + ``qemu-img`` uses the unsafe mode if ``-u`` is specified. In this mode, only the backing file name and format of *FILENAME* is changed without any checks on the file contents. The user must take care of specifying the correct new backing file, or the guest-visible @@ -735,7 +735,7 @@ Command description: sizes accordingly. Failure to do so will result in data loss! When shrinking images, the ``--shrink`` option must be given. This informs - qemu-img that the user acknowledges all loss of data beyond the truncated + ``qemu-img`` that the user acknowledges all loss of data beyond the truncated image's end. After using this command to grow a disk image, you must use file system and diff --git a/docs/tools/qemu-nbd.rst b/docs/tools/qemu-nbd.rst index 726cd18960..6031f96893 100644 --- a/docs/tools/qemu-nbd.rst +++ b/docs/tools/qemu-nbd.rst @@ -38,7 +38,7 @@ driver options if ``--image-opts`` is specified. supported. The common object types that it makes sense to define are the ``secret`` object, which is used to supply passwords and/or encryption keys, and the ``tls-creds`` object, which is used to supply TLS - credentials for the qemu-nbd server or client. + credentials for the ``qemu-nbd`` server or client. .. option:: -p, --port=PORT @@ -238,7 +238,7 @@ daemon: Expose the guest-visible contents of a qcow2 file via a block device /dev/nbd0 (and possibly creating /dev/nbd0p1 and friends for partitions found within), then disconnect the device when done. -Access to bind qemu-nbd to an /dev/nbd device generally requires root +Access to bind ``qemu-nbd`` to a /dev/nbd device generally requires root privileges, and may also require the execution of ``modprobe nbd`` to enable the kernel NBD client module. *CAUTION*: Do not use this method to mount filesystems from an untrusted guest image - a diff --git a/docs/tools/qemu-storage-daemon.rst b/docs/tools/qemu-storage-daemon.rst index b8ef4486f1..3e5a9dc032 100644 --- a/docs/tools/qemu-storage-daemon.rst +++ b/docs/tools/qemu-storage-daemon.rst @@ -10,9 +10,10 @@ Synopsis Description ----------- -qemu-storage-daemon provides disk image functionality from QEMU, qemu-img, and -qemu-nbd in a long-running process controlled via QMP commands without running -a virtual machine. It can export disk images, run block job operations, and +``qemu-storage-daemon`` provides disk image functionality from QEMU, +``qemu-img``, and ``qemu-nbd`` in a long-running process controlled via QMP +commands without running a virtual machine. +It can export disk images, run block job operations, and perform other disk-related operations. The daemon is controlled via a QMP monitor and initial configuration from the command-line. diff --git a/docs/tools/virtiofsd.rst b/docs/tools/virtiofsd.rst index cc31402830..07ac0be551 100644 --- a/docs/tools/virtiofsd.rst +++ b/docs/tools/virtiofsd.rst @@ -136,8 +136,8 @@ Extended attribute (xattr) mapping By default the name of xattr's used by the client are passed through to the server file system. This can be a problem where either those xattr names are used by something on the server (e.g. selinux client/server confusion) or if the -virtiofsd is running in a container with restricted privileges where it cannot -access some attributes. +``virtiofsd`` is running in a container with restricted privileges where it +cannot access some attributes. Mapping syntax ~~~~~~~~~~~~~~ From 33a0c404fb90a3fa8eea6ebf5c535fc7bc0b9912 Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Mon, 22 Nov 2021 18:17:17 +0000 Subject: [PATCH 36/79] hw/intc/arm_gicv3_its: Revert version increments in vmstate_its Commit 18f6290a6a ("hw/intc: GICv3 ITS initial framework") incremented version_id and minimum_version_id fields of VMStateDescription vmstate_its. This breaks the migration between 6.2 and 6.1 with the following message: qemu-system-aarch64: savevm: unsupported version 1 for 'arm_gicv3_its' v0 qemu-system-aarch64: load of migration failed: Invalid argument Revert that change. Signed-off-by: Eric Auger Message-id: 20211122171020.1195483-1-eric.auger@redhat.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/intc/arm_gicv3_its_common.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c index 7d7f3882e7..90b85f1e25 100644 --- a/hw/intc/arm_gicv3_its_common.c +++ b/hw/intc/arm_gicv3_its_common.c @@ -50,8 +50,6 @@ static int gicv3_its_post_load(void *opaque, int version_id) static const VMStateDescription vmstate_its = { .name = "arm_gicv3_its", - .version_id = 1, - .minimum_version_id = 1, .pre_save = gicv3_its_pre_save, .post_load = gicv3_its_post_load, .priority = MIG_PRI_GICV3_ITS, From 87bf1fe5cbffefe6b7ee13a7015ae285250ad2db Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 18 Nov 2021 15:46:14 -0500 Subject: [PATCH 37/79] python/machine: add @sock_dir property Analogous to temp_dir and log_dir, add a sock_dir property that defaults to @temp_dir -- instead of base_temp_dir -- when the user hasn't overridden the sock dir value in the initializer. This gives us a much more unique directory to put sockfiles in by default. Signed-off-by: John Snow Reviewed-by: Willian Rampazzo Message-id: 20211118204620.1897674-2-jsnow@redhat.com Signed-off-by: John Snow --- python/qemu/machine/machine.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py index a487c39745..b1dd77b538 100644 --- a/python/qemu/machine/machine.py +++ b/python/qemu/machine/machine.py @@ -134,8 +134,9 @@ class QEMUMachine: self._qmp_timer = qmp_timer self._name = name or "qemu-%d" % os.getpid() + self._temp_dir: Optional[str] = None self._base_temp_dir = base_temp_dir - self._sock_dir = sock_dir or self._base_temp_dir + self._sock_dir = sock_dir self._log_dir = log_dir if monitor_address is not None: @@ -143,7 +144,7 @@ class QEMUMachine: self._remove_monitor_sockfile = False else: self._monitor_address = os.path.join( - self._sock_dir, f"{self._name}-monitor.sock" + self.sock_dir, f"{self._name}-monitor.sock" ) self._remove_monitor_sockfile = True @@ -163,14 +164,13 @@ class QEMUMachine: self._qmp_set = True # Enable QMP monitor by default. self._qmp_connection: Optional[QEMUMonitorProtocol] = None self._qemu_full_args: Tuple[str, ...] = () - self._temp_dir: Optional[str] = None self._launched = False self._machine: Optional[str] = None self._console_index = 0 self._console_set = False self._console_device_type: Optional[str] = None self._console_address = os.path.join( - self._sock_dir, f"{self._name}-console.sock" + self.sock_dir, f"{self._name}-console.sock" ) self._console_socket: Optional[socket.socket] = None self._remove_files: List[str] = [] @@ -816,6 +816,15 @@ class QEMUMachine: dir=self._base_temp_dir) return self._temp_dir + @property + def sock_dir(self) -> str: + """ + Returns the directory used for sockfiles by this machine. + """ + if self._sock_dir: + return self._sock_dir + return self.temp_dir + @property def log_dir(self) -> str: """ From 6eeb3de7e1aff91ce6e092a39f85946d12664385 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 18 Nov 2021 15:46:15 -0500 Subject: [PATCH 38/79] python/machine: remove _remove_monitor_sockfile property It doesn't matter if it was the user or the class itself that specified where the sockfile should be created; the fact is that if we are using a sockfile here, we created it and we can clean it up. Signed-off-by: John Snow Reviewed-by: Willian Rampazzo Message-id: 20211118204620.1897674-3-jsnow@redhat.com Signed-off-by: John Snow --- python/qemu/machine/machine.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py index b1dd77b538..ea9e07805d 100644 --- a/python/qemu/machine/machine.py +++ b/python/qemu/machine/machine.py @@ -141,12 +141,10 @@ class QEMUMachine: if monitor_address is not None: self._monitor_address = monitor_address - self._remove_monitor_sockfile = False else: self._monitor_address = os.path.join( self.sock_dir, f"{self._name}-monitor.sock" ) - self._remove_monitor_sockfile = True self._console_log_path = console_log if self._console_log_path: @@ -315,8 +313,7 @@ class QEMUMachine: self._remove_files.append(self._console_address) if self._qmp_set: - if self._remove_monitor_sockfile: - assert isinstance(self._monitor_address, str) + if isinstance(self._monitor_address, str): self._remove_files.append(self._monitor_address) self._qmp_connection = QEMUMonitorProtocol( self._monitor_address, From 72b17fe715056c96ea73f187ab46721788b3a782 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 18 Nov 2021 15:46:16 -0500 Subject: [PATCH 39/79] python/machine: add instance disambiguator to default nickname MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If you create two instances of QEMUMachine(), they'll both create the same nickname by default -- which is not that helpful. Luckily, they'll both create unique temporary directories ... but due to user configuration, they may share logging and sockfile directories, meaning two instances can collide. The Python logging will also be quite confusing, with no differentiation between the two instances. Add an instance disambiguator (The memory address of the instance) to the default nickname to foolproof this in all cases. Signed-off-by: John Snow Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Willian Rampazzo Message-id: 20211118204620.1897674-4-jsnow@redhat.com Signed-off-by: John Snow --- python/qemu/machine/machine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py index ea9e07805d..ad529fd92a 100644 --- a/python/qemu/machine/machine.py +++ b/python/qemu/machine/machine.py @@ -133,7 +133,7 @@ class QEMUMachine: self._wrapper = wrapper self._qmp_timer = qmp_timer - self._name = name or "qemu-%d" % os.getpid() + self._name = name or f"qemu-{os.getpid()}-{id(self):02x}" self._temp_dir: Optional[str] = None self._base_temp_dir = base_temp_dir self._sock_dir = sock_dir From b1ca99199320fcc010f407b84ac00d96e7e4baa1 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 18 Nov 2021 15:46:17 -0500 Subject: [PATCH 40/79] python/machine: move more variable initializations to _pre_launch No need to clear them only to set them later. Signed-off-by: John Snow Reviewed-by: Willian Rampazzo Message-id: 20211118204620.1897674-5-jsnow@redhat.com Signed-off-by: John Snow --- python/qemu/machine/machine.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py index ad529fd92a..f92e73de40 100644 --- a/python/qemu/machine/machine.py +++ b/python/qemu/machine/machine.py @@ -327,6 +327,14 @@ class QEMUMachine: self._qemu_log_path = os.path.join(self.log_dir, self._name + ".log") self._qemu_log_file = open(self._qemu_log_path, 'wb') + self._iolog = None + self._qemu_full_args = tuple(chain( + self._wrapper, + [self._binary], + self._base_args, + self._args + )) + def _post_launch(self) -> None: if self._qmp_connection: self._qmp.accept(self._qmp_timer) @@ -390,8 +398,6 @@ class QEMUMachine: if self._launched: raise QEMUMachineError('VM already launched') - self._iolog = None - self._qemu_full_args = () try: self._launch() self._launched = True @@ -410,12 +416,6 @@ class QEMUMachine: Launch the VM and establish a QMP connection """ self._pre_launch() - self._qemu_full_args = tuple( - chain(self._wrapper, - [self._binary], - self._base_args, - self._args) - ) LOG.debug('VM launch command: %r', ' '.join(self._qemu_full_args)) # Cleaning up of this subprocess is guaranteed by _do_shutdown. From 1611e6cf4e7163f6102b37010a8b7e7120f468b5 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 18 Nov 2021 15:46:18 -0500 Subject: [PATCH 41/79] python/machine: handle "fast" QEMU terminations In the case that the QEMU process actually launches -- but then dies so quickly that we can't establish a QMP connection to it -- QEMUMachine currently calls _post_shutdown() assuming that it never launched the VM process. This isn't true, though: it "merely" may have failed to establish a QMP connection and the process is in the middle of its own exit path. If we don't wait for the subprocess, the caller may get a bogus `None` return for .exitcode(). This behavior was observed from device-crash-test; after the switch to Async QMP, the timings were changed such that it was now seemingly possible to witness the failure of "vm.launch()" *prior* to the exitcode becoming available. The semantic of the `_launched` property is changed in this patch. Instead of representing the condition "launch() executed successfully", it will now represent "has forked a child process successfully". This way, wait() when called in the exit path won't become a no-op. Signed-off-by: John Snow Reviewed-by: Willian Rampazzo Message-id: 20211118204620.1897674-6-jsnow@redhat.com Signed-off-by: John Snow --- python/qemu/machine/machine.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py index f92e73de40..67ab06ca2b 100644 --- a/python/qemu/machine/machine.py +++ b/python/qemu/machine/machine.py @@ -349,9 +349,6 @@ class QEMUMachine: Called to cleanup the VM instance after the process has exited. May also be called after a failed launch. """ - # Comprehensive reset for the failed launch case: - self._early_cleanup() - try: self._close_qmp_connection() except Exception as err: # pylint: disable=broad-except @@ -400,9 +397,16 @@ class QEMUMachine: try: self._launch() - self._launched = True except: - self._post_shutdown() + # We may have launched the process but it may + # have exited before we could connect via QMP. + # Assume the VM didn't launch or is exiting. + # If we don't wait for the process, exitcode() may still be + # 'None' by the time control is ceded back to the caller. + if self._launched: + self.wait() + else: + self._post_shutdown() LOG.debug('Error launching VM') if self._qemu_full_args: @@ -426,6 +430,7 @@ class QEMUMachine: stderr=subprocess.STDOUT, shell=False, close_fds=False) + self._launched = True self._post_launch() def _close_qmp_connection(self) -> None: @@ -457,8 +462,8 @@ class QEMUMachine: """ Perform any cleanup that needs to happen before the VM exits. - May be invoked by both soft and hard shutdown in failover scenarios. - Called additionally by _post_shutdown for comprehensive cleanup. + This method may be called twice upon shutdown, once each by soft + and hard shutdown in failover scenarios. """ # If we keep the console socket open, we may deadlock waiting # for QEMU to exit, while QEMU is waiting for the socket to From 206439cd8937a3dc556537074d5d37e5d74eb0d0 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 18 Nov 2021 15:46:19 -0500 Subject: [PATCH 42/79] scripts/device-crash-test: Use a QMP timeout Despite all the previous fixes, it's still possible for device-crash-test to wedge itself in the case that QEMU terminates *so quickly* that it doesn't even begin a connection attempt to our QMP client. Python will just joyfully wait ad infinitum for a connection that will now never arrive. The real fix is to use asyncio to simultaneously poll both the health of the launched process AND the connection attempt. That's quite a bit more invasive than just setting a connection timeout, though. Do the very simplest thing for now. Signed-off-by: John Snow Message-id: 20211118204620.1897674-7-jsnow@redhat.com Signed-off-by: John Snow --- scripts/device-crash-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/device-crash-test b/scripts/device-crash-test index 1c73dac93e..7fbd99158b 100755 --- a/scripts/device-crash-test +++ b/scripts/device-crash-test @@ -353,7 +353,7 @@ def checkOneCase(args, testcase): '-device', qemuOptsEscape(device)] cmdline = ' '.join([binary] + args) dbg("will launch QEMU: %s", cmdline) - vm = QEMUMachine(binary=binary, args=args) + vm = QEMUMachine(binary=binary, args=args, qmp_timer=15) exc = None exc_traceback = None From a57cb3e23d5ac918a69d0aab918470ff0b429ff9 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 18 Nov 2021 15:46:20 -0500 Subject: [PATCH 43/79] python/aqmp: fix send_fd_scm for python 3.6.x 3.6 doesn't play keepaway with the socket object, so we don't need to go fishing for it on this version. In fact, so long as 'sendmsg' is still available, it's probably preferable to just use that method and only go fishing for forbidden details when we absolutely have to. Reported-by: Thomas Huth Signed-off-by: John Snow Reviewed-by: Willian Rampazzo Message-id: 20211118204620.1897674-8-jsnow@redhat.com Signed-off-by: John Snow --- python/qemu/aqmp/qmp_client.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/python/qemu/aqmp/qmp_client.py b/python/qemu/aqmp/qmp_client.py index f987da02eb..8105e29fa8 100644 --- a/python/qemu/aqmp/qmp_client.py +++ b/python/qemu/aqmp/qmp_client.py @@ -639,9 +639,12 @@ class QMPClient(AsyncProtocol[Message], Events): if sock.family != socket.AF_UNIX: raise AQMPError("Sending file descriptors requires a UNIX socket.") - # Void the warranty sticker. - # Access to sendmsg in asyncio is scheduled for removal in Python 3.11. - sock = sock._sock # pylint: disable=protected-access + if not hasattr(sock, 'sendmsg'): + # We need to void the warranty sticker. + # Access to sendmsg is scheduled for removal in Python 3.11. + # Find the real backing socket to use it anyway. + sock = sock._sock # pylint: disable=protected-access + sock.sendmsg( [b' '], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, struct.pack('@i', fd))] From c6cda6a44a8adaeb30bd6dc185f021809625433d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 12 Nov 2021 21:55:59 -0700 Subject: [PATCH 44/79] linux-user: Add host_signal_set_pc to set pc in mcontext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new function host_signal_set_pc to set the next pc in an mcontext. The caller should ensure this is a valid PC for execution. Acked-by: Laurent Vivier Signed-off-by: Warner Losh Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20211113045603.60391-2-imp@bsdimp.com> Signed-off-by: Richard Henderson --- linux-user/host/aarch64/host-signal.h | 5 +++++ linux-user/host/alpha/host-signal.h | 5 +++++ linux-user/host/arm/host-signal.h | 5 +++++ linux-user/host/i386/host-signal.h | 5 +++++ linux-user/host/mips/host-signal.h | 5 +++++ linux-user/host/ppc/host-signal.h | 5 +++++ linux-user/host/riscv/host-signal.h | 5 +++++ linux-user/host/s390/host-signal.h | 5 +++++ linux-user/host/sparc/host-signal.h | 9 +++++++++ linux-user/host/x86_64/host-signal.h | 5 +++++ 10 files changed, 54 insertions(+) diff --git a/linux-user/host/aarch64/host-signal.h b/linux-user/host/aarch64/host-signal.h index 0c0b08383a..9770b36dc1 100644 --- a/linux-user/host/aarch64/host-signal.h +++ b/linux-user/host/aarch64/host-signal.h @@ -35,6 +35,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc) return uc->uc_mcontext.pc; } +static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) +{ + uc->uc_mcontext.pc = pc; +} + static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) { struct _aarch64_ctx *hdr; diff --git a/linux-user/host/alpha/host-signal.h b/linux-user/host/alpha/host-signal.h index e080be412f..f4c942948a 100644 --- a/linux-user/host/alpha/host-signal.h +++ b/linux-user/host/alpha/host-signal.h @@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc) return uc->uc_mcontext.sc_pc; } +static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) +{ + uc->uc_mcontext.sc_pc = pc; +} + static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) { uint32_t *pc = (uint32_t *)host_signal_pc(uc); diff --git a/linux-user/host/arm/host-signal.h b/linux-user/host/arm/host-signal.h index efb165c0c5..6c095773c0 100644 --- a/linux-user/host/arm/host-signal.h +++ b/linux-user/host/arm/host-signal.h @@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc) return uc->uc_mcontext.arm_pc; } +static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) +{ + uc->uc_mcontext.arm_pc = pc; +} + static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) { /* diff --git a/linux-user/host/i386/host-signal.h b/linux-user/host/i386/host-signal.h index 4c8eef99ce..abe1ece5c9 100644 --- a/linux-user/host/i386/host-signal.h +++ b/linux-user/host/i386/host-signal.h @@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc) return uc->uc_mcontext.gregs[REG_EIP]; } +static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) +{ + uc->uc_mcontext.gregs[REG_EIP] = pc; +} + static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) { return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe diff --git a/linux-user/host/mips/host-signal.h b/linux-user/host/mips/host-signal.h index ef341f7c20..c666ed8c3f 100644 --- a/linux-user/host/mips/host-signal.h +++ b/linux-user/host/mips/host-signal.h @@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc) return uc->uc_mcontext.pc; } +static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) +{ + uc->uc_mcontext.pc = pc; +} + #if defined(__misp16) || defined(__mips_micromips) #error "Unsupported encoding" #endif diff --git a/linux-user/host/ppc/host-signal.h b/linux-user/host/ppc/host-signal.h index a491c413dc..1d8e658ff7 100644 --- a/linux-user/host/ppc/host-signal.h +++ b/linux-user/host/ppc/host-signal.h @@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc) return uc->uc_mcontext.regs->nip; } +static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) +{ + uc->uc_mcontext.regs->nip = pc; +} + static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) { return uc->uc_mcontext.regs->trap != 0x400 diff --git a/linux-user/host/riscv/host-signal.h b/linux-user/host/riscv/host-signal.h index 3b168cb58b..a4f170efb0 100644 --- a/linux-user/host/riscv/host-signal.h +++ b/linux-user/host/riscv/host-signal.h @@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc) return uc->uc_mcontext.__gregs[REG_PC]; } +static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) +{ + uc->uc_mcontext.__gregs[REG_PC] = pc; +} + static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) { /* diff --git a/linux-user/host/s390/host-signal.h b/linux-user/host/s390/host-signal.h index 26990e4893..a524f2ab00 100644 --- a/linux-user/host/s390/host-signal.h +++ b/linux-user/host/s390/host-signal.h @@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc) return uc->uc_mcontext.psw.addr; } +static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) +{ + uc->uc_mcontext.psw.addr = pc; +} + static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) { uint16_t *pinsn = (uint16_t *)host_signal_pc(uc); diff --git a/linux-user/host/sparc/host-signal.h b/linux-user/host/sparc/host-signal.h index 5e71d33f8e..7342936071 100644 --- a/linux-user/host/sparc/host-signal.h +++ b/linux-user/host/sparc/host-signal.h @@ -20,6 +20,15 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc) #endif } +static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) +{ +#ifdef __arch64__ + uc->uc_mcontext.mc_gregs[MC_PC] = pc; +#else + uc->uc_mcontext.gregs[REG_PC] = pc; +#endif +} + static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) { uint32_t insn = *(uint32_t *)host_signal_pc(uc); diff --git a/linux-user/host/x86_64/host-signal.h b/linux-user/host/x86_64/host-signal.h index 883d2fcf65..c71d597eb2 100644 --- a/linux-user/host/x86_64/host-signal.h +++ b/linux-user/host/x86_64/host-signal.h @@ -15,6 +15,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc) return uc->uc_mcontext.gregs[REG_RIP]; } +static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) +{ + uc->uc_mcontext.gregs[REG_RIP] = pc; +} + static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) { return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe From 07637888687bfecf3c0cc8351c5c24f29a611691 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 12 Nov 2021 21:56:00 -0700 Subject: [PATCH 45/79] linux-user/signal.c: Create a common rewind_if_in_safe_syscall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All instances of rewind_if_in_safe_syscall are the same, differing only in how the instruction point is fetched from the ucontext and the size of the registers. Use host_signal_pc and new host_signal_set_pc interfaces to fetch the pointer to the PC and adjust if needed. Delete all the old copies of rewind_if_in_safe_syscall. Acked-by: Laurent Vivier Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211113045603.60391-3-imp@bsdimp.com> [rth: include safe-syscall.h, simplify ifdefs] Signed-off-by: Richard Henderson --- linux-user/host/aarch64/hostdep.h | 20 -------------------- linux-user/host/arm/hostdep.h | 20 -------------------- linux-user/host/i386/hostdep.h | 20 -------------------- linux-user/host/ppc64/hostdep.h | 20 -------------------- linux-user/host/riscv/hostdep.h | 20 -------------------- linux-user/host/s390x/hostdep.h | 20 -------------------- linux-user/host/x86_64/hostdep.h | 20 -------------------- linux-user/safe-syscall.h | 3 +++ linux-user/signal.c | 15 ++++++++++++--- 9 files changed, 15 insertions(+), 143 deletions(-) diff --git a/linux-user/host/aarch64/hostdep.h b/linux-user/host/aarch64/hostdep.h index a8d41a21ad..39299d798a 100644 --- a/linux-user/host/aarch64/hostdep.h +++ b/linux-user/host/aarch64/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* Adjust the signal context to rewind out of safe-syscall if we're in it */ -static inline void rewind_if_in_safe_syscall(void *puc) -{ - ucontext_t *uc = puc; - __u64 *pcreg = &uc->uc_mcontext.pc; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/arm/hostdep.h b/linux-user/host/arm/hostdep.h index 9276fe6ceb..86b137875a 100644 --- a/linux-user/host/arm/hostdep.h +++ b/linux-user/host/arm/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* Adjust the signal context to rewind out of safe-syscall if we're in it */ -static inline void rewind_if_in_safe_syscall(void *puc) -{ - ucontext_t *uc = puc; - unsigned long *pcreg = &uc->uc_mcontext.arm_pc; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/i386/hostdep.h b/linux-user/host/i386/hostdep.h index 073be74d87..ce7136501f 100644 --- a/linux-user/host/i386/hostdep.h +++ b/linux-user/host/i386/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* Adjust the signal context to rewind out of safe-syscall if we're in it */ -static inline void rewind_if_in_safe_syscall(void *puc) -{ - ucontext_t *uc = puc; - greg_t *pcreg = &uc->uc_mcontext.gregs[REG_EIP]; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/ppc64/hostdep.h b/linux-user/host/ppc64/hostdep.h index 98979ad917..0c290dd904 100644 --- a/linux-user/host/ppc64/hostdep.h +++ b/linux-user/host/ppc64/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* Adjust the signal context to rewind out of safe-syscall if we're in it */ -static inline void rewind_if_in_safe_syscall(void *puc) -{ - ucontext_t *uc = puc; - unsigned long *pcreg = &uc->uc_mcontext.gp_regs[PT_NIP]; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/riscv/hostdep.h b/linux-user/host/riscv/hostdep.h index 2ba07456ae..7f67c22868 100644 --- a/linux-user/host/riscv/hostdep.h +++ b/linux-user/host/riscv/hostdep.h @@ -11,24 +11,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* Adjust the signal context to rewind out of safe-syscall if we're in it */ -static inline void rewind_if_in_safe_syscall(void *puc) -{ - ucontext_t *uc = puc; - unsigned long *pcreg = &uc->uc_mcontext.__gregs[REG_PC]; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/s390x/hostdep.h b/linux-user/host/s390x/hostdep.h index 4f0171f36f..d801145854 100644 --- a/linux-user/host/s390x/hostdep.h +++ b/linux-user/host/s390x/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* Adjust the signal context to rewind out of safe-syscall if we're in it */ -static inline void rewind_if_in_safe_syscall(void *puc) -{ - ucontext_t *uc = puc; - unsigned long *pcreg = &uc->uc_mcontext.psw.addr; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/x86_64/hostdep.h b/linux-user/host/x86_64/hostdep.h index a4fefb5114..9c62bd26bd 100644 --- a/linux-user/host/x86_64/hostdep.h +++ b/linux-user/host/x86_64/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* Adjust the signal context to rewind out of safe-syscall if we're in it */ -static inline void rewind_if_in_safe_syscall(void *puc) -{ - ucontext_t *uc = puc; - greg_t *pcreg = &uc->uc_mcontext.gregs[REG_RIP]; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/safe-syscall.h b/linux-user/safe-syscall.h index 6bc0390262..aaa9ffc0e2 100644 --- a/linux-user/safe-syscall.h +++ b/linux-user/safe-syscall.h @@ -127,6 +127,9 @@ #ifdef HAVE_SAFE_SYSCALL /* The core part of this function is implemented in assembly */ extern long safe_syscall_base(int *pending, long number, ...); +/* These are defined by the safe-syscall.inc.S file */ +extern char safe_syscall_start[]; +extern char safe_syscall_end[]; #define safe_syscall(...) \ ({ \ diff --git a/linux-user/signal.c b/linux-user/signal.c index 81c45bfce9..6d5e5b698c 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -31,6 +31,7 @@ #include "trace.h" #include "signal-common.h" #include "host-signal.h" +#include "safe-syscall.h" static struct target_sigaction sigact_table[TARGET_NSIG]; @@ -793,12 +794,20 @@ int queue_signal(CPUArchState *env, int sig, int si_type, return 1; /* indicates that the signal was queued */ } -#ifndef HAVE_SAFE_SYSCALL + +/* Adjust the signal context to rewind out of safe-syscall if we're in it */ static inline void rewind_if_in_safe_syscall(void *puc) { - /* Default version: never rewind */ -} +#ifdef HAVE_SAFE_SYSCALL + ucontext_t *uc = (ucontext_t *)puc; + uintptr_t pcreg = host_signal_pc(uc); + + if (pcreg > (uintptr_t)safe_syscall_start + && pcreg < (uintptr_t)safe_syscall_end) { + host_signal_set_pc(uc, (uintptr_t)safe_syscall_start); + } #endif +} static void host_signal_handler(int host_sig, siginfo_t *info, void *puc) { From 22c36b75c8a07f34a6516a8d79f38c74530727a1 Mon Sep 17 00:00:00 2001 From: Daniella Lee Date: Fri, 19 Nov 2021 19:25:53 +0800 Subject: [PATCH 46/79] block/vvfat.c fix leak when failure occurs Function vvfat_open called function enable_write_target and init_directories, and these functions malloc new memory for BDRVVVFATState::qcow_filename, BDRVVVFATState::used_clusters, and BDRVVVFATState::cluster_buff. When the specified folder does not exist ,it may contains memory leak. After init_directories function is executed, the vvfat_open return -EIO, and bdrv_open_driver goto label open_failed, the program use g_free(bs->opaque) to release BDRVVVFATState struct without members mentioned. command line: qemu-system-x86_64 -hdb -usb -device usb-storage,drive=fat16 -drive file=fat:rw:fat-type=16:"", id=fat16,format=raw,if=none enable_write_target called: (gdb) bt at ../block/vvfat.c:3114 flags=155650, errp=0x7fffffffd780) at ../block/vvfat.c:1236 node_name=0x0, options=0x555556fa45d0, open_flags=155650, errp=0x7fffffffd890) at ../block.c:1558 errp=0x7fffffffd890) at ../block.c:1852 reference=0x0, options=0x555556fa45d0, flags=40962, parent=0x555556f98cd0, child_class=0x555556b1d6a0 , child_role=19, errp=0x7fffffffda90) at ../block.c:3779 options=0x555556f9cfc0, bdref_key=0x555556239bb8 "file", parent=0x555556f98cd0, child_class=0x555556b1d6a0 , child_role=19, allow_none=true, errp=0x7fffffffda90) at ../block.c:3419 reference=0x0, options=0x555556f9cfc0, flags=8194, parent=0x0, child_class=0x0, child_role=0, errp=0x555556c98c40 ) at ../block.c:3726 options=0x555556f757b0, flags=0, errp=0x555556c98c40 ) at ../block.c:3872 options=0x555556f757b0, flags=0, errp=0x555556c98c40 ) at ../block/block-backend.c:436 bs_opts=0x555556f757b0, errp=0x555556c98c40 ) at ../blockdev.c:608 errp=0x555556c98c40 ) at ../blockdev.c:992 ...... Signed-off-by: Daniella Lee Message-Id: <20211119112553.352222-1-daniellalee111@gmail.com> [hreitz: Took commit message from v1] Signed-off-by: Hanna Reitz --- block/vvfat.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index 05e78e3c27..5dacc6cfac 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -1279,8 +1279,18 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags, qemu_co_mutex_init(&s->lock); - ret = 0; + qemu_opts_del(opts); + + return 0; + fail: + g_free(s->qcow_filename); + s->qcow_filename = NULL; + g_free(s->cluster_buffer); + s->cluster_buffer = NULL; + g_free(s->used_clusters); + s->used_clusters = NULL; + qemu_opts_del(opts); return ret; } @@ -3118,7 +3128,7 @@ static int enable_write_target(BlockDriverState *bs, Error **errp) int size = sector2cluster(s, s->sector_count); QDict *options; - s->used_clusters = calloc(size, 1); + s->used_clusters = g_malloc0(size); array_init(&(s->commits), sizeof(commit_t)); @@ -3166,8 +3176,6 @@ static int enable_write_target(BlockDriverState *bs, Error **errp) return 0; err: - g_free(s->qcow_filename); - s->qcow_filename = NULL; return ret; } From cb5a24d7f692ad129f019f3b670531eccfe14415 Mon Sep 17 00:00:00 2001 From: Hanna Reitz Date: Wed, 17 Nov 2021 16:17:06 +0100 Subject: [PATCH 47/79] iotests: Use aes-128-cbc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Our gnutls crypto backend (which is the default as of 8bd0931f6) supports neither twofish-128 nor the CTR mode. CBC and aes-128 are supported by all of our backends (as far as I can tell), so use aes-128-cbc in our iotests. (We could also use e.g. aes-256-cbc, but the different key sizes would lead to different key slot offsets and so change the reference output more, which is why I went with aes-128.) Signed-off-by: Hanna Reitz Message-Id: <20211117151707.52549-2-hreitz@redhat.com> Reviewed-by: Daniel P. Berrangé Tested-by: Thomas Huth --- tests/qemu-iotests/206 | 4 ++-- tests/qemu-iotests/206.out | 6 +++--- tests/qemu-iotests/210 | 4 ++-- tests/qemu-iotests/210.out | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206 index c3cdad4ce4..10eff343f7 100755 --- a/tests/qemu-iotests/206 +++ b/tests/qemu-iotests/206 @@ -162,8 +162,8 @@ with iotests.FilePath('t.qcow2') as disk_path, \ 'encrypt': { 'format': 'luks', 'key-secret': 'keysec0', - 'cipher-alg': 'twofish-128', - 'cipher-mode': 'ctr', + 'cipher-alg': 'aes-128', + 'cipher-mode': 'cbc', 'ivgen-alg': 'plain64', 'ivgen-hash-alg': 'md5', 'hash-alg': 'sha1', diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out index 3593e8e9c2..80cd274223 100644 --- a/tests/qemu-iotests/206.out +++ b/tests/qemu-iotests/206.out @@ -97,7 +97,7 @@ Format specific information: === Successful image creation (encrypted) === -{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "encrypt": {"cipher-alg": "twofish-128", "cipher-mode": "ctr", "format": "luks", "hash-alg": "sha1", "iter-time": 10, "ivgen-alg": "plain64", "ivgen-hash-alg": "md5", "key-secret": "keysec0"}, "file": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2"}, "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "encrypt": {"cipher-alg": "aes-128", "cipher-mode": "cbc", "format": "luks", "hash-alg": "sha1", "iter-time": 10, "ivgen-alg": "plain64", "ivgen-hash-alg": "md5", "key-secret": "keysec0"}, "file": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2"}, "size": 33554432}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -115,10 +115,10 @@ Format specific information: encrypt: ivgen alg: plain64 hash alg: sha1 - cipher alg: twofish-128 + cipher alg: aes-128 uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX format: luks - cipher mode: ctr + cipher mode: cbc slots: [0]: active: true diff --git a/tests/qemu-iotests/210 b/tests/qemu-iotests/210 index 5a62ed4dd1..a4dcc5fe59 100755 --- a/tests/qemu-iotests/210 +++ b/tests/qemu-iotests/210 @@ -83,8 +83,8 @@ with iotests.FilePath('t.luks') as disk_path, \ }, 'size': size, 'key-secret': 'keysec0', - 'cipher-alg': 'twofish-128', - 'cipher-mode': 'ctr', + 'cipher-alg': 'aes-128', + 'cipher-mode': 'cbc', 'ivgen-alg': 'plain64', 'ivgen-hash-alg': 'md5', 'hash-alg': 'sha1', diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out index 55c0844370..96d9f749dd 100644 --- a/tests/qemu-iotests/210.out +++ b/tests/qemu-iotests/210.out @@ -59,7 +59,7 @@ Format specific information: {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cipher-alg": "twofish-128", "cipher-mode": "ctr", "driver": "luks", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.luks"}, "hash-alg": "sha1", "iter-time": 10, "ivgen-alg": "plain64", "ivgen-hash-alg": "md5", "key-secret": "keysec0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cipher-alg": "aes-128", "cipher-mode": "cbc", "driver": "luks", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.luks"}, "hash-alg": "sha1", "iter-time": 10, "ivgen-alg": "plain64", "ivgen-hash-alg": "md5", "key-secret": "keysec0", "size": 67108864}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -71,9 +71,9 @@ encrypted: yes Format specific information: ivgen alg: plain64 hash alg: sha1 - cipher alg: twofish-128 + cipher alg: aes-128 uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - cipher mode: ctr + cipher mode: cbc slots: [0]: active: true From 4dd218fd0717ed3cddb69c01eeb9da630107d89d Mon Sep 17 00:00:00 2001 From: Hanna Reitz Date: Wed, 17 Nov 2021 16:17:07 +0100 Subject: [PATCH 48/79] iotests/149: Skip on unsupported ciphers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Whenever qemu-img or qemu-io report that some cipher is unsupported, skip the whole test, because that is probably because qemu has been configured with the gnutls crypto backend. We could taylor the algorithm list to what gnutls supports, but this is a test that is run rather rarely anyway (because it requires password-less sudo), and so it seems better and easier to skip it. When this test is intentionally run to check LUKS compatibility, it seems better not to limit the algorithms but keep the list extensive. Signed-off-by: Hanna Reitz Message-Id: <20211117151707.52549-3-hreitz@redhat.com> Reviewed-by: Daniel P. Berrangé --- tests/qemu-iotests/149 | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/tests/qemu-iotests/149 b/tests/qemu-iotests/149 index 328fd05a4c..d49646ca60 100755 --- a/tests/qemu-iotests/149 +++ b/tests/qemu-iotests/149 @@ -230,6 +230,18 @@ def create_image(config, size_mb): fn.truncate(size_mb * 1024 * 1024) +def check_cipher_support(config, output): + """Check the output of qemu-img or qemu-io for mention of the respective + cipher algorithm being unsupported, and if so, skip this test. + (Returns `output` for convenience.)""" + + if 'Unsupported cipher algorithm' in output: + iotests.notrun('Unsupported cipher algorithm ' + f'{config.cipher}-{config.keylen}-{config.mode}; ' + 'consider configuring qemu with a different crypto ' + 'backend') + return output + def qemu_img_create(config, size_mb): """Create and format a disk image with LUKS using qemu-img""" @@ -253,7 +265,8 @@ def qemu_img_create(config, size_mb): "%dM" % size_mb] iotests.log("qemu-img " + " ".join(args), filters=[iotests.filter_test_dir]) - iotests.log(iotests.qemu_img_pipe(*args), filters=[iotests.filter_test_dir]) + iotests.log(check_cipher_support(config, iotests.qemu_img_pipe(*args)), + filters=[iotests.filter_test_dir]) def qemu_io_image_args(config, dev=False): """Get the args for access an image or device with qemu-io""" @@ -279,8 +292,8 @@ def qemu_io_write_pattern(config, pattern, offset_mb, size_mb, dev=False): args = ["-c", "write -P 0x%x %dM %dM" % (pattern, offset_mb, size_mb)] args.extend(qemu_io_image_args(config, dev)) iotests.log("qemu-io " + " ".join(args), filters=[iotests.filter_test_dir]) - iotests.log(iotests.qemu_io(*args), filters=[iotests.filter_test_dir, - iotests.filter_qemu_io]) + iotests.log(check_cipher_support(config, iotests.qemu_io(*args)), + filters=[iotests.filter_test_dir, iotests.filter_qemu_io]) def qemu_io_read_pattern(config, pattern, offset_mb, size_mb, dev=False): @@ -291,8 +304,8 @@ def qemu_io_read_pattern(config, pattern, offset_mb, size_mb, dev=False): args = ["-c", "read -P 0x%x %dM %dM" % (pattern, offset_mb, size_mb)] args.extend(qemu_io_image_args(config, dev)) iotests.log("qemu-io " + " ".join(args), filters=[iotests.filter_test_dir]) - iotests.log(iotests.qemu_io(*args), filters=[iotests.filter_test_dir, - iotests.filter_qemu_io]) + iotests.log(check_cipher_support(config, iotests.qemu_io(*args)), + filters=[iotests.filter_test_dir, iotests.filter_qemu_io]) def test_once(config, qemu_img=False): From 14d02cfbe4adaeebe7cb833a8cc71191352cf03b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 24 Nov 2021 16:50:54 +0100 Subject: [PATCH 49/79] Update version for v6.2.0-rc2 release Signed-off-by: Richard Henderson --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 61d04b724a..030e1ce3b5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.2.91 +6.2.92 From dd4b0de45965538f19bb40c7ddaaba384a8c613a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 25 Nov 2021 10:44:43 +0100 Subject: [PATCH 50/79] Fix version for v6.2.0-rc2 release Typo while setting VERSION in the tag commit. Signed-off-by: Richard Henderson --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 030e1ce3b5..f5664554ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.2.92 +6.1.92 From bede01170e9cb8f9ac9c6a0665ee9f3989a57e6a Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 23 Nov 2021 13:28:59 +0100 Subject: [PATCH 51/79] hw/arm/virt: Extend nested and mte checks to hvf The virt machine has properties to enable MTE and Nested Virtualization support. However, its check to ensure the backing accel implementation supports it today only looks for KVM and bails out if it finds it. Extend the checks to HVF as well as it does not support either today. This will cause QEMU to print a useful error message rather than silently ignoring the attempt by the user to enable either MTE or the Virtualization extensions. Reported-by: saar amar Signed-off-by: Alexander Graf Message-id: 20211123122859.22452-1-agraf@csgraf.de Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/virt.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 369552ad45..30da05dfe0 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -49,6 +49,7 @@ #include "sysemu/runstate.h" #include "sysemu/tpm.h" #include "sysemu/kvm.h" +#include "sysemu/hvf.h" #include "hw/loader.h" #include "qapi/error.h" #include "qemu/bitops.h" @@ -1969,15 +1970,17 @@ static void machvirt_init(MachineState *machine) exit(1); } - if (vms->virt && kvm_enabled()) { - error_report("mach-virt: KVM does not support providing " - "Virtualization extensions to the guest CPU"); + if (vms->virt && (kvm_enabled() || hvf_enabled())) { + error_report("mach-virt: %s does not support providing " + "Virtualization extensions to the guest CPU", + kvm_enabled() ? "KVM" : "HVF"); exit(1); } - if (vms->mte && kvm_enabled()) { - error_report("mach-virt: KVM does not support providing " - "MTE to the guest CPU"); + if (vms->mte && (kvm_enabled() || hvf_enabled())) { + error_report("mach-virt: %s does not support providing " + "MTE to the guest CPU", + kvm_enabled() ? "KVM" : "HVF"); exit(1); } From 2f459cd1a80d24189598fd3416e270d1feb7dc87 Mon Sep 17 00:00:00 2001 From: Shashi Mallela Date: Wed, 24 Nov 2021 13:22:46 -0500 Subject: [PATCH 52/79] hw/intc: cannot clear GICv3 ITS CTLR[Enabled] bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When Enabled bit is cleared in GITS_CTLR,ITS feature continues to be enabled.This patch fixes the issue. Signed-off-by: Shashi Mallela Tested-by: Alex Bennée Reviewed-by: Peter Maydell Message-id: 20211124182246.67691-1-shashi.mallela@linaro.org Signed-off-by: Peter Maydell --- hw/intc/arm_gicv3_its.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index 84bcbb5f56..c929a9cb5c 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -896,13 +896,14 @@ static bool its_writel(GICv3ITSState *s, hwaddr offset, switch (offset) { case GITS_CTLR: - s->ctlr |= (value & ~(s->ctlr)); - - if (s->ctlr & ITS_CTLR_ENABLED) { + if (value & R_GITS_CTLR_ENABLED_MASK) { + s->ctlr |= ITS_CTLR_ENABLED; extract_table_params(s); extract_cmdq_params(s); s->creadr = 0; process_cmdq(s); + } else { + s->ctlr &= ~ITS_CTLR_ENABLED; } break; case GITS_CBASER: From 101f27f3c834842238624b6c0205be3281883878 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Wed, 24 Nov 2021 20:20:05 +0000 Subject: [PATCH 53/79] hw/intc/arm_gicv3: Update cached state after LPI state changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The logic of gicv3_redist_update() is as follows: * it must be called in any code path that changes the state of (only) redistributor interrupts * if it finds a redistributor interrupt that is (now) higher priority than the previous highest-priority pending interrupt, then this must be the new highest-priority pending interrupt * if it does *not* find a better redistributor interrupt, then: - if the previous state was "no interrupts pending" then the new state is still "no interrupts pending" - if the previous best interrupt was not a redistributor interrupt then that remains the best interrupt - if the previous best interrupt *was* a redistributor interrupt, then the new best interrupt must be some non-redistributor interrupt, but we don't know which so must do a full scan In commit 17fb5e36aabd4b2c125 we effectively added the LPI interrupts as a kind of "redistributor interrupt" for this purpose, by adding cs->hpplpi to the set of things that gicv3_redist_update() considers before it gives up and decides to do a full scan of distributor interrupts. However we didn't quite get this right: * the condition check for "was the previous best interrupt a redistributor interrupt" must be updated to include LPIs in what it considers to be redistributor interrupts * every code path which updates the LPI state which gicv3_redist_update() checks must also call gicv3_redist_update(): this is cs->hpplpi and the GICR_CTLR ENABLE_LPIS bit This commit fixes this by: * correcting the test on cs->hppi.irq in gicv3_redist_update() * making gicv3_redist_update_lpi() always call gicv3_redist_update() * introducing a new gicv3_redist_update_lpi_only() for the one callsite (the post-load hook) which must not call gicv3_redist_update() * making gicv3_redist_lpi_pending() always call gicv3_redist_update(), either directly or via gicv3_redist_update_lpi() * removing a couple of now-unnecessary calls to gicv3_redist_update() from some callers of those two functions * calling gicv3_redist_update() when the GICR_CTLR ENABLE_LPIS bit is cleared (This means that the not-file-local gicv3_redist_* LPI related functions now all take care of the updates of internally cached GICv3 information, in the same way the older functions gicv3_redist_set_irq() and gicv3_redist_send_sgi() do.) The visible effect of this bug was that when the guest acknowledged an LPI by reading ICC_IAR1_EL1, we marked it as not pending in the LPI data structure but still left it in cs->hppi so we would offer it to the guest again. In particular for setups using an emulated GICv3 and ITS and using devices which use LPIs (ie PCI devices) a Linux guest would complain "irq 54: nobody cared" and then hang. (The hang was intermittent, presumably depending on the timing between different interrupts arriving and being completed.) Signed-off-by: Peter Maydell Tested-by: Alex Bennée Reviewed-by: Alex Bennée Message-id: 20211124202005.989935-1-peter.maydell@linaro.org --- hw/intc/arm_gicv3.c | 6 ++++-- hw/intc/arm_gicv3_redist.c | 14 ++++++++++---- hw/intc/gicv3_internal.h | 17 +++++++++++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c index c6282984b1..9f5f815db9 100644 --- a/hw/intc/arm_gicv3.c +++ b/hw/intc/arm_gicv3.c @@ -186,7 +186,9 @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs) * interrupt has reduced in priority and any other interrupt could * now be the new best one). */ - if (!seenbetter && cs->hppi.prio != 0xff && cs->hppi.irq < GIC_INTERNAL) { + if (!seenbetter && cs->hppi.prio != 0xff && + (cs->hppi.irq < GIC_INTERNAL || + cs->hppi.irq >= GICV3_LPI_INTID_START)) { gicv3_full_update_noirqset(cs->gic); } } @@ -354,7 +356,7 @@ static void arm_gicv3_post_load(GICv3State *s) * pending interrupt, but don't set IRQ or FIQ lines. */ for (i = 0; i < s->num_cpu; i++) { - gicv3_redist_update_lpi(&s->cpu[i]); + gicv3_redist_update_lpi_only(&s->cpu[i]); } gicv3_full_update_noirqset(s); /* Repopulate the cache of GICv3CPUState pointers for target CPUs */ diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c index 424e7e28a8..c8ff3eca08 100644 --- a/hw/intc/arm_gicv3_redist.c +++ b/hw/intc/arm_gicv3_redist.c @@ -256,9 +256,10 @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset, cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS; /* Check for any pending interr in pending table */ gicv3_redist_update_lpi(cs); - gicv3_redist_update(cs); } else { cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS; + /* cs->hppi might have been an LPI; recalculate */ + gicv3_redist_update(cs); } } return MEMTX_OK; @@ -571,7 +572,7 @@ static void gicv3_redist_check_lpi_priority(GICv3CPUState *cs, int irq) } } -void gicv3_redist_update_lpi(GICv3CPUState *cs) +void gicv3_redist_update_lpi_only(GICv3CPUState *cs) { /* * This function scans the LPI pending table and for each pending @@ -614,6 +615,12 @@ void gicv3_redist_update_lpi(GICv3CPUState *cs) } } +void gicv3_redist_update_lpi(GICv3CPUState *cs) +{ + gicv3_redist_update_lpi_only(cs); + gicv3_redist_update(cs); +} + void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level) { /* @@ -651,6 +658,7 @@ void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level) */ if (level) { gicv3_redist_check_lpi_priority(cs, irq); + gicv3_redist_update(cs); } else { if (irq == cs->hpplpi.irq) { gicv3_redist_update_lpi(cs); @@ -673,8 +681,6 @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level) /* set/clear the pending bit for this irq */ gicv3_redist_lpi_pending(cs, irq, level); - - gicv3_redist_update(cs); } void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level) diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h index a0369dace7..70f34ee495 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -463,7 +463,24 @@ void gicv3_dist_set_irq(GICv3State *s, int irq, int level); void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level); void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level); void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level); +/** + * gicv3_redist_update_lpi: + * @cs: GICv3CPUState + * + * Scan the LPI pending table and recalculate the highest priority + * pending LPI and also the overall highest priority pending interrupt. + */ void gicv3_redist_update_lpi(GICv3CPUState *cs); +/** + * gicv3_redist_update_lpi_only: + * @cs: GICv3CPUState + * + * Scan the LPI pending table and recalculate cs->hpplpi only, + * without calling gicv3_redist_update() to recalculate the overall + * highest priority pending interrupt. This should be called after + * an incoming migration has loaded new state. + */ +void gicv3_redist_update_lpi_only(GICv3CPUState *cs); void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns); void gicv3_init_cpuif(GICv3State *s); From b74d7c0e50ac4bde85c0ff629bfc23cdf378e62c Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 26 Nov 2021 16:39:14 +0000 Subject: [PATCH 54/79] hw/intc/arm_gicv3: Add new gicv3_intid_is_special() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GICv3/v4 pseudocode has a function IsSpecial() which returns true if passed a "special" interrupt ID number (anything between 1020 and 1023 inclusive). We open-code this condition in a couple of places, so abstract it out into a new function gicv3_intid_is_special(). Signed-off-by: Peter Maydell Reviewed-by: Marc Zyngier Reviewed-by: Alex Bennée --- hw/intc/arm_gicv3_cpuif.c | 4 ++-- hw/intc/gicv3_internal.h | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c index 3fe5de8ad7..7fbc36ff41 100644 --- a/hw/intc/arm_gicv3_cpuif.c +++ b/hw/intc/arm_gicv3_cpuif.c @@ -997,7 +997,7 @@ static uint64_t icc_iar0_read(CPUARMState *env, const ARMCPRegInfo *ri) intid = icc_hppir0_value(cs, env); } - if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) { + if (!gicv3_intid_is_special(intid)) { icc_activate_irq(cs, intid); } @@ -1020,7 +1020,7 @@ static uint64_t icc_iar1_read(CPUARMState *env, const ARMCPRegInfo *ri) intid = icc_hppir1_value(cs, env); } - if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) { + if (!gicv3_intid_is_special(intid)) { icc_activate_irq(cs, intid); } diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h index 70f34ee495..b9c37453b0 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -411,6 +411,19 @@ FIELD(MAPC, RDBASE, 16, 32) /* Functions internal to the emulated GICv3 */ +/** + * gicv3_intid_is_special: + * @intid: interrupt ID + * + * Return true if @intid is a special interrupt ID (1020 to + * 1023 inclusive). This corresponds to the GIC spec pseudocode + * IsSpecial() function. + */ +static inline bool gicv3_intid_is_special(int intid) +{ + return intid >= INTID_SECURE && intid <= INTID_SPURIOUS; +} + /** * gicv3_redist_update: * @cs: GICv3CPUState for this redistributor From 7abba7c638ab809e626f379617cb8590a733eabf Mon Sep 17 00:00:00 2001 From: Cindy Lu Date: Tue, 9 Nov 2021 10:37:44 +0800 Subject: [PATCH 55/79] virtio-mmio : fix the crash in the vm shutdown The root cause for this crash is the ioeventfd not stopped while the VM stop. The callback for vmstate_change was not implement in virtio-mmio bus Reproduce step load the vm with -M microvm \ -netdev tap,id=net0,vhostforce,script=no,downscript=no \ -device virtio-net-device,netdev=net0\ After the VM boot, login the vm and then shutdown the vm System will crash [Current thread is 1 (Thread 0x7ffff6edde00 (LWP 374378))] (gdb) bt 0 0x00005555558f18b4 in qemu_flush_or_purge_queued_packets (purge=false, nc=0x55500252e850) at ../net/net.c:636 1 qemu_flush_queued_packets (nc=0x55500252e850) at ../net/net.c:656 2 0x0000555555b6c363 in virtio_queue_notify_vq (vq=0x7fffe7e2b010) at ../hw/virtio/virtio.c:2339 3 virtio_queue_host_notifier_read (n=0x7fffe7e2b08c) at ../hw/virtio/virtio.c:3583 4 0x0000555555de7b5a in aio_dispatch_handler (ctx=ctx@entry=0x5555567c5780, node=0x555556b83fd0) at ../util/aio-posix.c:329 5 0x0000555555de8454 in aio_dispatch_ready_handlers (ready_list=, ctx=) at ../util/aio-posix.c:359 6 aio_poll (ctx=0x5555567c5780, blocking=blocking@entry=false) at ../util/aio-posix.c:662 7 0x0000555555cce0cc in monitor_cleanup () at ../monitor/monitor.c:645 8 0x0000555555b06bd2 in qemu_cleanup () at ../softmmu/runstate.c:822 9 0x000055555586e693 in main (argc=, argv=, envp=) at ../softmmu/main.c:51 Signed-off-by: Cindy Lu Message-Id: <20211109023744.22387-1-lulu@redhat.com> Acked-by: Jason Wang Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-mmio.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 7b3ebca178..72da12fea5 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -817,6 +817,17 @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev) return path; } +static void virtio_mmio_vmstate_change(DeviceState *d, bool running) +{ + VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); + + if (running) { + virtio_mmio_start_ioeventfd(proxy); + } else { + virtio_mmio_stop_ioeventfd(proxy); + } +} + static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data) { BusClass *bus_class = BUS_CLASS(klass); @@ -832,6 +843,7 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data) k->ioeventfd_enabled = virtio_mmio_ioeventfd_enabled; k->ioeventfd_assign = virtio_mmio_ioeventfd_assign; k->pre_plugged = virtio_mmio_pre_plugged; + k->vmstate_change = virtio_mmio_vmstate_change; k->has_variable_vring_alignment = true; bus_class->max_dev = 1; bus_class->get_dev_path = virtio_mmio_bus_get_dev_path; From 9323f892b39d133eb69b301484bf7b2f3f49737d Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Thu, 18 Nov 2021 14:32:23 +0100 Subject: [PATCH 56/79] failover: fix unplug pending detection Failover needs to detect the end of the PCI unplug to start migration after the VFIO card has been unplugged. To do that, a flag is set in pcie_cap_slot_unplug_request_cb() and reset in pcie_unplug_device(). But since 17858a169508 ("hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35") we have switched to ACPI unplug and these functions are not called anymore and the flag not set. So failover migration is not able to detect if card is really unplugged and acts as it's done as soon as it's started. So it doesn't wait the end of the unplug to start the migration. We don't see any problem when we test that because ACPI unplug is faster than PCIe native hotplug and when the migration really starts the unplug operation is already done. See c000a9bd06ea ("pci: mark device having guest unplug request pending") a99c4da9fc2a ("pci: mark devices partially unplugged") Signed-off-by: Laurent Vivier Reviewed-by: Ani Sinha Message-Id: <20211118133225.324937-4-lvivier@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/pcihp.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index f610a25d2e..30405b5113 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -222,9 +222,27 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo PCIDevice *dev = PCI_DEVICE(qdev); if (PCI_SLOT(dev->devfn) == slot) { if (!acpi_pcihp_pc_no_hotplug(s, dev)) { - hotplug_ctrl = qdev_get_hotplug_handler(qdev); - hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort); - object_unparent(OBJECT(qdev)); + /* + * partially_hotplugged is used by virtio-net failover: + * failover has asked the guest OS to unplug the device + * but we need to keep some references to the device + * to be able to plug it back in case of failure so + * we don't execute hotplug_handler_unplug(). + */ + if (dev->partially_hotplugged) { + /* + * pending_deleted_event is set to true when + * virtio-net failover asks to unplug the device, + * and set to false here when the operation is done + * This is used by the migration loop to detect the + * end of the operation and really start the migration. + */ + qdev->pending_deleted_event = false; + } else { + hotplug_ctrl = qdev_get_hotplug_handler(qdev); + hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort); + object_unparent(OBJECT(qdev)); + } } } } @@ -396,6 +414,12 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev, return; } + /* + * pending_deleted_event is used by virtio-net failover to detect the + * end of the unplug operation, the flag is set to false in + * acpi_pcihp_eject_slot() when the operation is completed. + */ + pdev->qdev.pending_deleted_event = true; s->acpi_pcihp_pci_status[bsel].down |= (1U << slot); acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS); } From 846a1e85da646c6006db429648389fc110f92d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= Date: Thu, 25 Nov 2021 11:16:13 +0100 Subject: [PATCH 57/79] vdpa: Add dummy receive callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qemu falls back on userland handlers even if vhost-user and vhost-vdpa cases. These assumes a tap device can handle the packets. If a vdpa device fail to start, it can trigger a sigsegv because of that. Add dummy receiver that returns no progress so it can keep running. Fixes: 1e0a84ea49 ("vhost-vdpa: introduce vhost-vdpa net client") Signed-off-by: Eugenio Pérez Message-Id: <20211125101614.76927-2-eperezma@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang --- net/vhost-vdpa.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index 2e3c22a8c7..25dd6dd975 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -170,9 +170,17 @@ static bool vhost_vdpa_check_peer_type(NetClientState *nc, ObjectClass *oc, return true; } +/** Dummy receive in case qemu falls back to userland tap networking */ +static ssize_t vhost_vdpa_receive(NetClientState *nc, const uint8_t *buf, + size_t size) +{ + return 0; +} + static NetClientInfo net_vhost_vdpa_info = { .type = NET_CLIENT_DRIVER_VHOST_VDPA, .size = sizeof(VhostVDPAState), + .receive = vhost_vdpa_receive, .cleanup = vhost_vdpa_cleanup, .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, .has_ufo = vhost_vdpa_has_ufo, From 90feffad2aafe856ed2af75313b2c1669ba671e9 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 26 Nov 2021 16:39:15 +0000 Subject: [PATCH 58/79] hw/intc/arm_gicv3: fix handling of LPIs in list registers It is valid for an OS to put virtual interrupt ID values into the list registers ICH_LR which are greater than 1023. This corresponds to (for example) KVM using the in-kernel emulated ITS to give a (nested) guest an ITS. LPIs are delivered by the L1 kernel to the L2 guest via the list registers in the same way as non-LPI interrupts. QEMU's code for handling writes to ICV_IARn (which happen when the L2 guest acknowledges an interrupt) and to ICV_EOIRn (which happen at the end of the interrupt) did not consider LPIs, so it would incorrectly treat interrupt IDs above 1023 as invalid. Fix this by using the correct condition, which is gicv3_intid_is_special(). Note that the condition in icv_dir_write() is correct -- LPIs are not valid there and so we want to ignore both "special" ID values and LPIs. (In the pseudocode this logic is in: - VirtualReadIAR0(), VirtualReadIAR1(), which call IsSpecial() - VirtualWriteEOIR0(), VirtualWriteEOIR1(), which call VirtualIdentifierValid(data, TRUE) meaning "LPIs OK" - VirtualWriteDIR(), which calls VirtualIdentifierValid(data, FALSE) meaning "LPIs not OK") This bug doesn't seem to have any visible effect on Linux L2 guests most of the time, because the two bugs cancel each other out: we neither mark the interrupt active nor deactivate it. However it does mean that the L2 vCPU priority while the LPI handler is running will not be correct, so the interrupt handler could be unexpectedly interrupted by a different interrupt. (NB: this has nothing to do with using QEMU's emulated ITS.) Signed-off-by: Peter Maydell Reviewed-by: Marc Zyngier --- hw/intc/arm_gicv3_cpuif.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c index 7fbc36ff41..7fba931450 100644 --- a/hw/intc/arm_gicv3_cpuif.c +++ b/hw/intc/arm_gicv3_cpuif.c @@ -653,7 +653,7 @@ static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri) if (thisgrp == grp && icv_hppi_can_preempt(cs, lr)) { intid = ich_lr_vintid(lr); - if (intid < INTID_SECURE) { + if (!gicv3_intid_is_special(intid)) { icv_activate_irq(cs, idx, grp); } else { /* Interrupt goes from Pending to Invalid */ @@ -1265,8 +1265,7 @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri, trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1, gicv3_redist_affid(cs), value); - if (irq >= GICV3_MAXIRQ) { - /* Also catches special interrupt numbers and LPIs */ + if (gicv3_intid_is_special(irq)) { return; } From 0fe7245d8b938f371556c100b0b6ec1d2b41e584 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 29 Nov 2021 11:08:40 +0800 Subject: [PATCH 59/79] virtio-balloon: process all in sgs for free_page_vq We only process the first in sg which may lead to the bitmap of the pages belongs to following sgs were not cleared. This may result more pages to be migrated. Fixing this by process all in sgs for free_page_vq. Acked-by: David Hildenbrand Signed-off-by: Jason Wang Message-Id: <20211129030841.3611-1-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-balloon.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index c6962fcbfe..17de2558cb 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -510,6 +510,7 @@ static bool get_free_page_hints(VirtIOBalloon *dev) VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtQueue *vq = dev->free_page_vq; bool ret = true; + int i; while (dev->block_iothread) { qemu_cond_wait(&dev->free_page_cond, &dev->free_page_lock); @@ -544,8 +545,10 @@ static bool get_free_page_hints(VirtIOBalloon *dev) } if (elem->in_num && dev->free_page_hint_status == FREE_PAGE_HINT_S_START) { - qemu_guest_free_page_hint(elem->in_sg[0].iov_base, - elem->in_sg[0].iov_len); + for (i = 0; i < elem->in_num; i++) { + qemu_guest_free_page_hint(elem->in_sg[i].iov_base, + elem->in_sg[i].iov_len); + } } out: From d3f1f940ebe43403feb1d12e4b5b9236aba50cb9 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 29 Nov 2021 11:08:41 +0800 Subject: [PATCH 60/79] virtio-balloon: correct used length Spec said: "and len the total of bytes written into the buffer." For inflateq, deflateq and statsq, we don't process in_sg so the used length should be zero. For free_page_vq, tough the pages could be changed by the device (in the destination), spec said: "Note: len is particularly useful for drivers using untrusted buffers: if a driver does not know exactly how much has been written by the device, the driver would have to zero the buffer in advance to ensure no data leakage occurs." So 0 should be used as well here. Signed-off-by: Jason Wang Message-Id: <20211129030841.3611-2-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: David Hildenbrand --- hw/virtio/virtio-balloon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 17de2558cb..9a4f491b54 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -231,7 +231,7 @@ static void balloon_stats_poll_cb(void *opaque) return; } - virtqueue_push(s->svq, s->stats_vq_elem, s->stats_vq_offset); + virtqueue_push(s->svq, s->stats_vq_elem, 0); virtio_notify(vdev, s->svq); g_free(s->stats_vq_elem); s->stats_vq_elem = NULL; @@ -438,7 +438,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) memory_region_unref(section.mr); } - virtqueue_push(vq, elem, offset); + virtqueue_push(vq, elem, 0); virtio_notify(vdev, vq); g_free(elem); virtio_balloon_pbp_free(&pbp); @@ -552,7 +552,7 @@ static bool get_free_page_hints(VirtIOBalloon *dev) } out: - virtqueue_push(vq, elem, 1); + virtqueue_push(vq, elem, 0); g_free(elem); return ret; } From 0192d6677c383d812fb23f572fda4e449e89d3f1 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 29 Nov 2021 11:36:18 +0800 Subject: [PATCH 61/79] intel-iommu: ignore leaf SNP bit in scalable mode When booting with scalable mode, I hit this error: qemu-system-x86_64: vtd_iova_to_slpte: detected splte reserve non-zero iova=0xfffff002, level=0x1slpte=0x102681803) qemu-system-x86_64: vtd_iommu_translate: detected translation failure (dev=01:00:00, iova=0xfffff002) qemu-system-x86_64: New fault is not recorded due to compression of faults This is because the SNP bit is set for second level page table since Linux kernel commit 6c00612d0cba1 ("iommu/vt-d: Report right snoop capability when using FL for IOVA") even if SC is not supported by the hardware. To unbreak the guest, ignore the leaf SNP bit for scalable mode first. In the future we may consider to add SC support. Signed-off-by: Jason Wang Message-Id: <20211129033618.3857-1-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Peter Xu --- hw/i386/intel_iommu.c | 6 ++++++ hw/i386/intel_iommu_internal.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 294499ee20..f584449d8d 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -3629,6 +3629,12 @@ static void vtd_init(IntelIOMMUState *s) vtd_spte_rsvd_large[3] = VTD_SPTE_LPAGE_L3_RSVD_MASK(s->aw_bits, x86_iommu->dt_supported); + if (s->scalable_mode) { + vtd_spte_rsvd[1] &= ~VTD_SPTE_SNP; + vtd_spte_rsvd_large[2] &= ~VTD_SPTE_SNP; + vtd_spte_rsvd_large[3] &= ~VTD_SPTE_SNP; + } + if (x86_iommu_ir_supported(x86_iommu)) { s->ecap |= VTD_ECAP_IR | VTD_ECAP_MHMV; if (s->intr_eim == ON_OFF_AUTO_ON) { diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 3d5487fe2c..a6c788049b 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -388,6 +388,8 @@ typedef union VTDInvDesc VTDInvDesc; #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8 /* Rsvd field masks for spte */ +#define VTD_SPTE_SNP 0x800ULL + #define VTD_SPTE_PAGE_L1_RSVD_MASK(aw, dt_supported) \ dt_supported ? \ (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM | VTD_SL_TM)) : \ From bacf58ca18f06f0b464466bf8c19945f19791feb Mon Sep 17 00:00:00 2001 From: Daniella Lee Date: Fri, 26 Nov 2021 14:13:24 +0800 Subject: [PATCH 62/79] Fix bad overflow check in hw/pci/pcie.c Orginal qemu commit hash:14d02cfbe4adaeebe7cb833a8cc71191352cf03b In function pcie_add_capability, an assert contains the "offset < offset + size" expression. Both variable offset and variable size are uint16_t, the comparison is always true due to type promotion. The next expression may be the same. It might be like this: Thread 1 "qemu-system-x86" hit Breakpoint 1, pcie_add_capability ( dev=0x555557ce5f10, cap_id=1, cap_ver=2 '\002', offset=256, size=72) at ../hw/pci/pcie.c:930 930 { (gdb) n 931 assert(offset >= PCI_CONFIG_SPACE_SIZE); (gdb) n 932 assert(offset < offset + size); (gdb) p offset $1 = 256 (gdb) p offset < offset + size $2 = 1 (gdb) set offset=65533 (gdb) p offset < offset + size $3 = 1 (gdb) p offset < (uint16_t)(offset + size) $4 = 0 Signed-off-by: Daniella Lee Message-Id: <20211126061324.47331-1-daniellalee111@gmail.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pcie.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index c5ed266337..d7d73a31e4 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -929,8 +929,8 @@ void pcie_add_capability(PCIDevice *dev, uint16_t offset, uint16_t size) { assert(offset >= PCI_CONFIG_SPACE_SIZE); - assert(offset < offset + size); - assert(offset + size <= PCIE_CONFIG_SPACE_SIZE); + assert(offset < (uint16_t)(offset + size)); + assert((uint16_t)(offset + size) <= PCIE_CONFIG_SPACE_SIZE); assert(size >= 8); assert(pci_is_express(dev)); From 0a761ce30338526213f74dfe9900b9213d4bbb0b Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Mon, 22 Nov 2021 16:56:02 +0100 Subject: [PATCH 63/79] linux-user: implement more loop ioctls LOOP_CONFIGURE is now used by losetup, and it cannot cope with ENOSYS. Signed-off-by: Andreas Schwab Reviewed-by: Laurent Vivier Message-Id: Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 4 ++++ linux-user/linux_loop.h | 2 ++ linux-user/syscall_defs.h | 4 ++++ linux-user/syscall_types.h | 6 ++++++ 4 files changed, 16 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 7193c3b226..f182d40190 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -637,6 +637,10 @@ IOCTL(LOOP_SET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64))) IOCTL(LOOP_GET_STATUS64, IOC_R, MK_PTR(MK_STRUCT(STRUCT_loop_info64))) IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT) + IOCTL(LOOP_SET_CAPACITY, 0, TYPE_INT) + IOCTL(LOOP_SET_DIRECT_IO, 0, TYPE_INT) + IOCTL(LOOP_SET_BLOCK_SIZE, 0, TYPE_INT) + IOCTL(LOOP_CONFIGURE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_config))) IOCTL(LOOP_CTL_ADD, 0, TYPE_INT) IOCTL(LOOP_CTL_REMOVE, 0, TYPE_INT) diff --git a/linux-user/linux_loop.h b/linux-user/linux_loop.h index c69fea11e4..f80b96f1ff 100644 --- a/linux-user/linux_loop.h +++ b/linux-user/linux_loop.h @@ -96,6 +96,8 @@ struct loop_info64 { #define LOOP_CHANGE_FD 0x4C06 #define LOOP_SET_CAPACITY 0x4C07 #define LOOP_SET_DIRECT_IO 0x4C08 +#define LOOP_SET_BLOCK_SIZE 0x4C09 +#define LOOP_CONFIGURE 0x4C0A /* /dev/loop-control interface */ #define LOOP_CTL_ADD 0x4C80 diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 41aaafbac1..0b13975937 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -1219,6 +1219,10 @@ struct target_rtc_pll_info { #define TARGET_LOOP_SET_STATUS64 0x4C04 #define TARGET_LOOP_GET_STATUS64 0x4C05 #define TARGET_LOOP_CHANGE_FD 0x4C06 +#define TARGET_LOOP_SET_CAPACITY 0x4C07 +#define TARGET_LOOP_SET_DIRECT_IO 0x4C08 +#define TARGET_LOOP_SET_BLOCK_SIZE 0x4C09 +#define TARGET_LOOP_CONFIGURE 0x4C0A #define TARGET_LOOP_CTL_ADD 0x4C80 #define TARGET_LOOP_CTL_REMOVE 0x4C81 diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index ba2c1518eb..c3b43f8022 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -201,6 +201,12 @@ STRUCT(loop_info64, MK_ARRAY(TYPE_CHAR, 32), /* lo_encrypt_key */ MK_ARRAY(TYPE_ULONGLONG, 2)) /* lo_init */ +STRUCT(loop_config, + TYPE_INT, /* fd */ + TYPE_INT, /* block_size */ + MK_STRUCT(STRUCT_loop_info64), /* info */ + MK_ARRAY(TYPE_ULONGLONG, 8)) /* __reserved */ + /* mag tape ioctls */ STRUCT(mtop, TYPE_SHORT, TYPE_INT) STRUCT(mtget, TYPE_LONG, TYPE_LONG, TYPE_LONG, TYPE_LONG, TYPE_LONG, From 48e14066ac10581db4e69f75eda107cfdafa6022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 29 Nov 2021 14:09:25 +0000 Subject: [PATCH 64/79] accel/tcg: introduce CF_NOIRQ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Here we introduce a new compiler flag to disable the checking of exit request (icount_decr.u32). This is useful when we want to ensure the next block cannot be preempted by an asynchronous event. Suggested-by: Richard Henderson Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Message-Id: <20211129140932.4115115-2-alex.bennee@linaro.org> --- include/exec/exec-all.h | 1 + include/exec/gen-icount.h | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 6bb2a0f7ec..35d8e93976 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -503,6 +503,7 @@ struct TranslationBlock { #define CF_USE_ICOUNT 0x00020000 #define CF_INVALID 0x00040000 /* TB is stale. Set with @jmp_lock held */ #define CF_PARALLEL 0x00080000 /* Generate code for a parallel context */ +#define CF_NOIRQ 0x00100000 /* Generate an uninterruptible TB */ #define CF_CLUSTER_MASK 0xff000000 /* Top 8 bits are cluster ID */ #define CF_CLUSTER_SHIFT 24 diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h index 610cba58fe..c57204ddad 100644 --- a/include/exec/gen-icount.h +++ b/include/exec/gen-icount.h @@ -21,7 +21,6 @@ static inline void gen_tb_start(const TranslationBlock *tb) { TCGv_i32 count; - tcg_ctx->exitreq_label = gen_new_label(); if (tb_cflags(tb) & CF_USE_ICOUNT) { count = tcg_temp_local_new_i32(); } else { @@ -42,7 +41,19 @@ static inline void gen_tb_start(const TranslationBlock *tb) icount_start_insn = tcg_last_op(); } - tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label); + /* + * Emit the check against icount_decr.u32 to see if we should exit + * unless we suppress the check with CF_NOIRQ. If we are using + * icount and have suppressed interruption the higher level code + * should have ensured we don't run more instructions than the + * budget. + */ + if (tb_cflags(tb) & CF_NOIRQ) { + tcg_ctx->exitreq_label = NULL; + } else { + tcg_ctx->exitreq_label = gen_new_label(); + tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label); + } if (tb_cflags(tb) & CF_USE_ICOUNT) { tcg_gen_st16_i32(count, cpu_env, @@ -74,8 +85,10 @@ static inline void gen_tb_end(const TranslationBlock *tb, int num_insns) tcgv_i32_arg(tcg_constant_i32(num_insns))); } - gen_set_label(tcg_ctx->exitreq_label); - tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED); + if (tcg_ctx->exitreq_label) { + gen_set_label(tcg_ctx->exitreq_label); + tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED); + } } #endif From aff0e204cb1f1c036a496c94c15f5dfafcd9b4b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 29 Nov 2021 14:09:26 +0000 Subject: [PATCH 65/79] accel/tcg: suppress IRQ check for special TBs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we set cpu->cflags_next_tb it is because we want to carefully control the execution of the next TB. Currently there is a race that causes the second stage of watchpoint handling to get ignored if an IRQ is processed before we finish executing the instruction that triggers the watchpoint. Use the new CF_NOIRQ facility to avoid the race. We also suppress IRQs when handling precise self modifying code to avoid unnecessary bouncing. Signed-off-by: Alex Bennée Cc: Pavel Dovgalyuk Fixes: https://gitlab.com/qemu-project/qemu/-/issues/245 Reviewed-by: Richard Henderson Message-Id: <20211129140932.4115115-3-alex.bennee@linaro.org> --- accel/tcg/cpu-exec.c | 9 +++++++++ accel/tcg/translate-all.c | 4 ++-- softmmu/physmem.c | 4 ++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 2d14d02f6c..409ec8c38c 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -721,6 +721,15 @@ static inline bool need_replay_interrupt(int interrupt_request) static inline bool cpu_handle_interrupt(CPUState *cpu, TranslationBlock **last_tb) { + /* + * If we have requested custom cflags with CF_NOIRQ we should + * skip checking here. Any pending interrupts will get picked up + * by the next TB we execute under normal cflags. + */ + if (cpu->cflags_next_tb != -1 && cpu->cflags_next_tb & CF_NOIRQ) { + return false; + } + /* Clear the interrupt flag now since we're processing * cpu->interrupt_request and cpu->exit_request. * Ensure zeroing happens before reading cpu->exit_request or diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index bd0bb81d08..bd71db59a9 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1738,7 +1738,7 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, if (current_tb_modified) { page_collection_unlock(pages); /* Force execution of one insn next time. */ - cpu->cflags_next_tb = 1 | curr_cflags(cpu); + cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu); mmap_unlock(); cpu_loop_exit_noexc(cpu); } @@ -1906,7 +1906,7 @@ static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc) #ifdef TARGET_HAS_PRECISE_SMC if (current_tb_modified) { /* Force execution of one insn next time. */ - cpu->cflags_next_tb = 1 | curr_cflags(cpu); + cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu); return true; } #endif diff --git a/softmmu/physmem.c b/softmmu/physmem.c index 314f8b439c..3524c04c2a 100644 --- a/softmmu/physmem.c +++ b/softmmu/physmem.c @@ -912,7 +912,7 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len, */ if (!cpu->can_do_io) { /* Force execution of one insn next time. */ - cpu->cflags_next_tb = 1 | CF_LAST_IO | curr_cflags(cpu); + cpu->cflags_next_tb = 1 | CF_LAST_IO | CF_NOIRQ | curr_cflags(cpu); cpu_loop_exit_restore(cpu, ra); } /* @@ -946,7 +946,7 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len, cpu_loop_exit(cpu); } else { /* Force execution of one insn next time. */ - cpu->cflags_next_tb = 1 | CF_LAST_IO | curr_cflags(cpu); + cpu->cflags_next_tb = 1 | CF_LAST_IO | CF_NOIRQ | curr_cflags(cpu); mmap_unlock(); cpu_loop_exit_noexc(cpu); } From a7c6e562e6f3f4e009c5dfa4e44cbbe908c4bf05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 29 Nov 2021 14:09:27 +0000 Subject: [PATCH 66/79] tests/avocado: fix tcg_plugin mem access count test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we cleaned up argument handling the test was missed. Fixes: 5ae589faad ("tests/plugins/mem: introduce "track" arg and make args not positional") Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211129140932.4115115-4-alex.bennee@linaro.org> --- tests/avocado/tcg_plugins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/avocado/tcg_plugins.py b/tests/avocado/tcg_plugins.py index 9ca1515c3b..642d2e49e3 100644 --- a/tests/avocado/tcg_plugins.py +++ b/tests/avocado/tcg_plugins.py @@ -131,7 +131,7 @@ class PluginKernelNormal(PluginKernelBase): suffix=".log") self.run_vm(kernel_path, kernel_command_line, - "tests/plugin/libmem.so,arg=both", plugin_log.name, + "tests/plugin/libmem.so,inline=true,callback=true", plugin_log.name, console_pattern, args=('-icount', 'shift=1')) From 86a41ac7fd488ce084175a30d1e5fd92dc37596b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 29 Nov 2021 14:09:28 +0000 Subject: [PATCH 67/79] plugins/meson.build: fix linker issue with weird paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alex Bennée Tested-by: Stefan Weil Fixes: https://gitlab.com/qemu-project/qemu/-/issues/712 Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211129140932.4115115-5-alex.bennee@linaro.org> --- plugins/meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/meson.build b/plugins/meson.build index aeb386ebae..b3de57853b 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -2,9 +2,9 @@ plugin_ldflags = [] # Modules need more symbols than just those in plugins/qemu-plugins.symbols if not enable_modules if 'CONFIG_HAS_LD_DYNAMIC_LIST' in config_host - plugin_ldflags = ['-Wl,--dynamic-list=' + (meson.project_build_root() / 'qemu-plugins-ld.symbols')] + plugin_ldflags = ['-Wl,--dynamic-list=qemu-plugins-ld.symbols'] elif 'CONFIG_HAS_LD_EXPORTED_SYMBOLS_LIST' in config_host - plugin_ldflags = ['-Wl,-exported_symbols_list,' + (meson.project_build_root() / 'qemu-plugins-ld64.symbols')] + plugin_ldflags = ['-Wl,-exported_symbols_list,qemu-plugins-ld64.symbols'] endif endif From a8e537fa4d61b29c5c0ab1395918ad63f7752b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 29 Nov 2021 14:09:29 +0000 Subject: [PATCH 68/79] gdbstub: handle a potentially racing TaskState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When dealing with multi-threaded userspace programs there is a race condition with the addition of cpu->opaque (aka TaskState). This is due to cpu_copy calling cpu_create which updates the global vCPU list. However the task state isn't set until later. This shouldn't be a problem because the new thread can't have executed anything yet but the gdbstub code does liberally iterate through the CPU list in various places. This sticking plaster ensure the not yet fully realized vCPU is given an pid of -1 which should be enough to ensure it doesn't show up anywhere else. In the longer term I think the code that manages the association between vCPUs and attached GDB processes could do with a clean-up and re-factor. Signed-off-by: Alex Bennée Tested-by: Richard Henderson Reviewed-by: Richard Henderson Cc: Richard Henderson Resolves: https://gitlab.com/qemu-project/qemu/-/issues/730 Message-Id: <20211129140932.4115115-6-alex.bennee@linaro.org> --- gdbstub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbstub.c b/gdbstub.c index 23baaef40e..141d7bc4ec 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -94,7 +94,7 @@ static inline int cpu_gdb_index(CPUState *cpu) { #if defined(CONFIG_USER_ONLY) TaskState *ts = (TaskState *) cpu->opaque; - return ts->ts_tid; + return ts ? ts->ts_tid : -1; #else return cpu->cpu_index + 1; #endif From 40525be5cbe768b23b427c6535c0b11bda80c851 Mon Sep 17 00:00:00 2001 From: Willian Rampazzo Date: Mon, 29 Nov 2021 14:09:30 +0000 Subject: [PATCH 69/79] MAINTAINERS: Remove me as a reviewer for the build and test/avocado MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove me as a reviewer for the Build and test automation and the Integration Testing with the Avocado Framework and add Beraldo Leal. Signed-off-by: Willian Rampazzo Reviewed-by: Beraldo Leal Message-Id: <20211122191124.31620-1-willianr@redhat.com> Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20211129140932.4115115-7-alex.bennee@linaro.org> --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index d3879aa3c1..8f5156bfa7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3469,7 +3469,7 @@ M: Alex Bennée M: Philippe Mathieu-Daudé M: Thomas Huth R: Wainer dos Santos Moschetta -R: Willian Rampazzo +R: Beraldo Leal S: Maintained F: .github/lockdown.yml F: .gitlab-ci.yml @@ -3507,7 +3507,7 @@ W: https://trello.com/b/6Qi1pxVn/avocado-qemu R: Cleber Rosa R: Philippe Mathieu-Daudé R: Wainer dos Santos Moschetta -R: Willian Rampazzo +R: Beraldo Leal S: Odd Fixes F: tests/avocado/ From 1e970158be18ed1142a8ba996448113f90848aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 29 Nov 2021 14:09:31 +0000 Subject: [PATCH 70/79] MAINTAINERS: Add section for Aarch64 GitLab custom runner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a MAINTAINERS section to cover the GitLab YAML config file containing the jobs run on the custom runner sponsored by the Works On Arm project [*]. [*] https://developer.arm.com/solutions/infrastructure/works-on-arm Suggested-by: Thomas Huth Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20211116163226.2719320-1-f4bug@amsat.org> Message-Id: <20211129140932.4115115-8-alex.bennee@linaro.org> --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8f5156bfa7..006a2293ba 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3511,6 +3511,12 @@ R: Beraldo Leal S: Odd Fixes F: tests/avocado/ +GitLab custom runner (Works On Arm Sponsored) +M: Alex Bennée +M: Philippe Mathieu-Daudé +S: Maintained +F: .gitlab-ci.d/custom-runners/ubuntu-20.04-aarch64.yml + Documentation ------------- Build system architecture From d5615bbf9103f01911df683cc3e4e85c49a92593 Mon Sep 17 00:00:00 2001 From: Juro Bystricky Date: Mon, 29 Nov 2021 14:09:32 +0000 Subject: [PATCH 71/79] tests/plugin/syscall.c: fix compiler warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix compiler warnings. The warnings can result in a broken build. This patch fixes warnings such as: In file included from /usr/include/glib-2.0/glib.h:111, from ../tests/plugin/syscall.c:13: ../tests/plugin/syscall.c: In function ‘print_entry’: /usr/include/glib-2.0/glib/glib-autocleanups.h:28:3: error: ‘out’ may be used uninitialized in this function [-Werror=maybe-uninitialized] g_free (*pp); ^~~~~~~~~~~~ ../tests/plugin/syscall.c:82:23: note: ‘out’ was declared here g_autofree gchar *out; ^~~ In file included from /usr/include/glib-2.0/glib.h:111, from ../tests/plugin/syscall.c:13: ../tests/plugin/syscall.c: In function ‘vcpu_syscall_ret’: /usr/include/glib-2.0/glib/glib-autocleanups.h:28:3: error: ‘out’ may be used uninitialized in this function [-Werror=maybe-uninitialized] g_free (*pp); ^~~~~~~~~~~~ ../tests/plugin/syscall.c:73:27: note: ‘out’ was declared here g_autofree gchar *out; ^~~ cc1: all warnings being treated as errors Signed-off-by: Juro Bystricky Signed-off-by: Alex Bennée Message-Id: <20211128011551.2115468-1-juro.bystricky@intel.com> Reviewed-by: Richard Henderson Message-Id: <20211129140932.4115115-9-alex.bennee@linaro.org> --- tests/plugin/syscall.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/plugin/syscall.c b/tests/plugin/syscall.c index 484b48de49..96040c578f 100644 --- a/tests/plugin/syscall.c +++ b/tests/plugin/syscall.c @@ -70,19 +70,17 @@ static void vcpu_syscall_ret(qemu_plugin_id_t id, unsigned int vcpu_idx, } g_mutex_unlock(&lock); } else { - g_autofree gchar *out; - out = g_strdup_printf("syscall #%" PRIi64 " returned -> %" PRIi64 "\n", - num, ret); + g_autofree gchar *out = g_strdup_printf( + "syscall #%" PRIi64 " returned -> %" PRIi64 "\n", num, ret); qemu_plugin_outs(out); } } static void print_entry(gpointer val, gpointer user_data) { - g_autofree gchar *out; SyscallStats *entry = (SyscallStats *) val; int64_t syscall_num = entry->num; - out = g_strdup_printf( + g_autofree gchar *out = g_strdup_printf( "%-13" PRIi64 "%-6" PRIi64 " %" PRIi64 "\n", syscall_num, entry->calls, entry->errors); qemu_plugin_outs(out); From 7bf00dfb51566070960e0b7977e41abba96c130e Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Mon, 29 Nov 2021 15:57:51 -0300 Subject: [PATCH 72/79] target/ppc: fix Hash64 MMU update of PTE bit R MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When updating the R bit of a PTE, the Hash64 MMU was using a wrong byte offset, causing the first byte of the adjacent PTE to be corrupted. This caused a panic when booting FreeBSD, using the Hash MMU. Fixes: a2dd4e83e76b ("ppc/hash64: Rework R and C bit updates") Signed-off-by: Leandro Lupori Signed-off-by: Cédric Le Goater --- hw/ppc/spapr.c | 8 ++++---- hw/ppc/spapr_softmmu.c | 2 +- target/ppc/mmu-hash64.c | 4 ++-- target/ppc/mmu-hash64.h | 5 +++++ 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 163c90388a..3b5fd749be 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1414,7 +1414,7 @@ void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex, kvmppc_write_hpte(ptex, pte0, pte1); } else { if (pte0 & HPTE64_V_VALID) { - stq_p(spapr->htab + offset + HASH_PTE_SIZE_64 / 2, pte1); + stq_p(spapr->htab + offset + HPTE64_DW1, pte1); /* * When setting valid, we write PTE1 first. This ensures * proper synchronization with the reading code in @@ -1430,7 +1430,7 @@ void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex, * ppc_hash64_pteg_search() */ smp_wmb(); - stq_p(spapr->htab + offset + HASH_PTE_SIZE_64 / 2, pte1); + stq_p(spapr->htab + offset + HPTE64_DW1, pte1); } } } @@ -1438,7 +1438,7 @@ void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex, static void spapr_hpte_set_c(PPCVirtualHypervisor *vhyp, hwaddr ptex, uint64_t pte1) { - hwaddr offset = ptex * HASH_PTE_SIZE_64 + 15; + hwaddr offset = ptex * HASH_PTE_SIZE_64 + HPTE64_DW1_C; SpaprMachineState *spapr = SPAPR_MACHINE(vhyp); if (!spapr->htab) { @@ -1454,7 +1454,7 @@ static void spapr_hpte_set_c(PPCVirtualHypervisor *vhyp, hwaddr ptex, static void spapr_hpte_set_r(PPCVirtualHypervisor *vhyp, hwaddr ptex, uint64_t pte1) { - hwaddr offset = ptex * HASH_PTE_SIZE_64 + 14; + hwaddr offset = ptex * HASH_PTE_SIZE_64 + HPTE64_DW1_R; SpaprMachineState *spapr = SPAPR_MACHINE(vhyp); if (!spapr->htab) { diff --git a/hw/ppc/spapr_softmmu.c b/hw/ppc/spapr_softmmu.c index f8924270ef..4ee03c83e4 100644 --- a/hw/ppc/spapr_softmmu.c +++ b/hw/ppc/spapr_softmmu.c @@ -426,7 +426,7 @@ static void new_hpte_store(void *htab, uint64_t pteg, int slot, addr += slot * HASH_PTE_SIZE_64; stq_p(addr, pte0); - stq_p(addr + HASH_PTE_SIZE_64 / 2, pte1); + stq_p(addr + HPTE64_DW1, pte1); } static int rehash_hpte(PowerPCCPU *cpu, diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 19832c4b46..da9fe99ff8 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -786,7 +786,7 @@ static void ppc_hash64_set_dsi(CPUState *cs, int mmu_idx, uint64_t dar, uint64_t static void ppc_hash64_set_r(PowerPCCPU *cpu, hwaddr ptex, uint64_t pte1) { - hwaddr base, offset = ptex * HASH_PTE_SIZE_64 + 16; + hwaddr base, offset = ptex * HASH_PTE_SIZE_64 + HPTE64_DW1_R; if (cpu->vhyp) { PPCVirtualHypervisorClass *vhc = @@ -803,7 +803,7 @@ static void ppc_hash64_set_r(PowerPCCPU *cpu, hwaddr ptex, uint64_t pte1) static void ppc_hash64_set_c(PowerPCCPU *cpu, hwaddr ptex, uint64_t pte1) { - hwaddr base, offset = ptex * HASH_PTE_SIZE_64 + 15; + hwaddr base, offset = ptex * HASH_PTE_SIZE_64 + HPTE64_DW1_C; if (cpu->vhyp) { PPCVirtualHypervisorClass *vhc = diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h index c5b2f97ff7..1496955d38 100644 --- a/target/ppc/mmu-hash64.h +++ b/target/ppc/mmu-hash64.h @@ -97,6 +97,11 @@ void ppc_hash64_finalize(PowerPCCPU *cpu); #define HPTE64_V_1TB_SEG 0x4000000000000000ULL #define HPTE64_V_VRMA_MASK 0x4001ffffff000000ULL +/* PTE offsets */ +#define HPTE64_DW1 (HASH_PTE_SIZE_64 / 2) +#define HPTE64_DW1_R (HPTE64_DW1 + 6) +#define HPTE64_DW1_C (HPTE64_DW1 + 7) + /* Format changes for ARCH v3 */ #define HPTE64_V_COMMON_BITS 0x000fffffffffffffULL #define HPTE64_R_3_0_SSIZE_SHIFT 58 From 24c4cd1311a45fa8ecfcde2f7b7afe84eb17dfac Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Tue, 30 Nov 2021 15:47:22 -0500 Subject: [PATCH 73/79] MAINTAINERS: Change my email address The ehabkost@redhat.com email address will stop working on 2021-12-01, change it to my personal email address. Signed-off-by: Eduardo Habkost Message-Id: <20211129163053.2506734-1-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost Message-Id: <20211130204722.2732997-2-ehabkost@redhat.com> Signed-off-by: Richard Henderson --- MAINTAINERS | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 006a2293ba..7543eb4d59 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -324,7 +324,7 @@ F: disas/sparc.c X86 TCG CPUs M: Paolo Bonzini M: Richard Henderson -M: Eduardo Habkost +M: Eduardo Habkost S: Maintained F: target/i386/tcg/ F: tests/tcg/i386/ @@ -1628,7 +1628,7 @@ F: include/hw/i386/microvm.h F: pc-bios/bios-microvm.bin Machine core -M: Eduardo Habkost +M: Eduardo Habkost M: Marcel Apfelbaum R: Philippe Mathieu-Daudé S: Supported @@ -2648,13 +2648,13 @@ F: backends/cryptodev*.c Python library M: John Snow M: Cleber Rosa -R: Eduardo Habkost +R: Eduardo Habkost S: Maintained F: python/ T: git https://gitlab.com/jsnow/qemu.git python Python scripts -M: Eduardo Habkost +M: Eduardo Habkost M: Cleber Rosa S: Odd Fixes F: scripts/*.py @@ -2730,7 +2730,7 @@ T: git https://github.com/mdroth/qemu.git qga QOM M: Paolo Bonzini R: Daniel P. Berrange -R: Eduardo Habkost +R: Eduardo Habkost S: Supported F: docs/qdev-device-use.txt F: hw/core/qdev* @@ -2750,7 +2750,7 @@ F: tests/unit/check-qom-proplist.c F: tests/unit/test-qdev-global-props.c QOM boilerplate conversion script -M: Eduardo Habkost +M: Eduardo Habkost S: Maintained F: scripts/codeconverter/ From 682aa69b1f4dd5f2905a94066fa4c853adc33251 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 1 Dec 2021 07:20:06 +0100 Subject: [PATCH 74/79] Update version for v6.2.0-rc3 release Signed-off-by: Richard Henderson --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f5664554ca..cbd3fe98d1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.1.92 +6.1.93 From b154791e7b6d4ca5cdcd54443484d97360bd7ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 24 Nov 2021 17:15:34 +0100 Subject: [PATCH 75/79] hw/block/fdc: Extract blk_create_empty_drive() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are going to re-use this code in the next commit, so extract it as a new blk_create_empty_drive() function. Inspired-by: Hanna Reitz Signed-off-by: Philippe Mathieu-Daudé Message-id: 20211124161536.631563-2-philmd@redhat.com Signed-off-by: John Snow --- hw/block/fdc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/block/fdc.c b/hw/block/fdc.c index fa933cd326..1dbf3f6028 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -61,6 +61,12 @@ } while (0) +/* Anonymous BlockBackend for empty drive */ +static BlockBackend *blk_create_empty_drive(void) +{ + return blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); +} + /********************************************************/ /* qdev floppy bus */ @@ -486,8 +492,7 @@ static void floppy_drive_realize(DeviceState *qdev, Error **errp) } if (!dev->conf.blk) { - /* Anonymous BlockBackend for an empty drive */ - dev->conf.blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); + dev->conf.blk = blk_create_empty_drive(); ret = blk_attach_dev(dev->conf.blk, qdev); assert(ret == 0); From 1ab95af033a419e7a64e2d58e67dd96b20af5233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 24 Nov 2021 17:15:35 +0100 Subject: [PATCH 76/79] hw/block/fdc: Kludge missing floppy drive to fix CVE-2021-20196 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guest might select another drive on the bus by setting the DRIVE_SEL bit of the DIGITAL OUTPUT REGISTER (DOR). The current controller model doesn't expect a BlockBackend to be NULL. A simple way to fix CVE-2021-20196 is to create an empty BlockBackend when it is missing. All further accesses will be safely handled, and the controller state machines keep behaving correctly. Cc: qemu-stable@nongnu.org Fixes: CVE-2021-20196 Reported-by: Gaoning Pan (Ant Security Light-Year Lab) Reviewed-by: Darren Kenny Reviewed-by: Hanna Reitz Signed-off-by: Philippe Mathieu-Daudé Message-id: 20211124161536.631563-3-philmd@redhat.com BugLink: https://bugs.launchpad.net/qemu/+bug/1912780 Resolves: https://gitlab.com/qemu-project/qemu/-/issues/338 Reviewed-by: Darren Kenny Reviewed-by: Hanna Reitz Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: John Snow --- hw/block/fdc.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 1dbf3f6028..21d18ac2e3 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -1166,7 +1166,19 @@ static FDrive *get_drv(FDCtrl *fdctrl, int unit) static FDrive *get_cur_drv(FDCtrl *fdctrl) { - return get_drv(fdctrl, fdctrl->cur_drv); + FDrive *cur_drv = get_drv(fdctrl, fdctrl->cur_drv); + + if (!cur_drv->blk) { + /* + * Kludge: empty drive line selected. Create an anonymous + * BlockBackend to avoid NULL deref with various BlockBackend + * API calls within this model (CVE-2021-20196). + * Due to the controller QOM model limitations, we don't + * attach the created to the controller device. + */ + cur_drv->blk = blk_create_empty_drive(); + } + return cur_drv; } /* Status A register : 0x00 (read-only) */ From cc20926e9b8077bff6813efc8dcdeae90d1a3b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 24 Nov 2021 17:15:36 +0100 Subject: [PATCH 77/79] tests/qtest/fdc-test: Add a regression test for CVE-2021-20196 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without the previous commit, when running 'make check-qtest-i386' with QEMU configured with '--enable-sanitizers' we get: AddressSanitizer:DEADLYSIGNAL ================================================================= ==287878==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000344 ==287878==The signal is caused by a WRITE memory access. ==287878==Hint: address points to the zero page. #0 0x564b2e5bac27 in blk_inc_in_flight block/block-backend.c:1346:5 #1 0x564b2e5bb228 in blk_pwritev_part block/block-backend.c:1317:5 #2 0x564b2e5bcd57 in blk_pwrite block/block-backend.c:1498:11 #3 0x564b2ca1cdd3 in fdctrl_write_data hw/block/fdc.c:2221:17 #4 0x564b2ca1b2f7 in fdctrl_write hw/block/fdc.c:829:9 #5 0x564b2dc49503 in portio_write softmmu/ioport.c:201:9 Add the reproducer for CVE-2021-20196. Suggested-by: Alexander Bulekov Reviewed-by: Darren Kenny Signed-off-by: Philippe Mathieu-Daudé Message-id: 20211124161536.631563-4-philmd@redhat.com Signed-off-by: John Snow --- tests/qtest/fdc-test.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/qtest/fdc-test.c b/tests/qtest/fdc-test.c index 26b69f7c5c..8f6eee84a4 100644 --- a/tests/qtest/fdc-test.c +++ b/tests/qtest/fdc-test.c @@ -32,6 +32,9 @@ /* TODO actually test the results and get rid of this */ #define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__)) +#define DRIVE_FLOPPY_BLANK \ + "-drive if=floppy,file=null-co://,file.read-zeroes=on,format=raw,size=1440k" + #define TEST_IMAGE_SIZE 1440 * 1024 #define FLOPPY_BASE 0x3f0 @@ -546,6 +549,40 @@ static void fuzz_registers(void) } } +static bool qtest_check_clang_sanitizer(void) +{ +#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer) + return true; +#else + g_test_skip("QEMU not configured using --enable-sanitizers"); + return false; +#endif +} +static void test_cve_2021_20196(void) +{ + QTestState *s; + + if (!qtest_check_clang_sanitizer()) { + return; + } + + s = qtest_initf("-nographic -m 32M -nodefaults " DRIVE_FLOPPY_BLANK); + + qtest_outw(s, 0x3f4, 0x0500); + qtest_outb(s, 0x3f5, 0x00); + qtest_outb(s, 0x3f5, 0x00); + qtest_outw(s, 0x3f4, 0x0000); + qtest_outb(s, 0x3f5, 0x00); + qtest_outw(s, 0x3f1, 0x0400); + qtest_outw(s, 0x3f4, 0x0000); + qtest_outw(s, 0x3f4, 0x0000); + qtest_outb(s, 0x3f5, 0x00); + qtest_outb(s, 0x3f5, 0x01); + qtest_outw(s, 0x3f1, 0x0500); + qtest_outb(s, 0x3f5, 0x00); + qtest_quit(s); +} + int main(int argc, char **argv) { int fd; @@ -576,6 +613,7 @@ int main(int argc, char **argv) qtest_add_func("/fdc/read_no_dma_18", test_read_no_dma_18); qtest_add_func("/fdc/read_no_dma_19", test_read_no_dma_19); qtest_add_func("/fdc/fuzz-registers", fuzz_registers); + qtest_add_func("/fdc/fuzz/cve_2021_20196", test_cve_2021_20196); ret = g_test_run(); From e7fa3377ccee50b0fd4596c06d2e62815e74328b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 3 Dec 2021 07:01:08 +0100 Subject: [PATCH 78/79] seabios: update submodule to 1.15.0 Update seabios to the final release. No code changes compared to the snapshot merged a few weeks ago. shortlog 64f37cc530f1..rel-1.15.0 --------------------------------- Kevin O'Connor (1): docs: Note v1.15.0 release Signed-off-by: Gerd Hoffmann --- roms/seabios | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roms/seabios b/roms/seabios index 64f37cc530..2dd4b9b3f8 160000 --- a/roms/seabios +++ b/roms/seabios @@ -1 +1 @@ -Subproject commit 64f37cc530f144e53c190c9e8209a51b58fd5c43 +Subproject commit 2dd4b9b3f84019668719344b40dba79d681be41c From 3bc90ac567f64fbe07b17b1174c85ec8a3e17d94 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 3 Dec 2021 07:09:22 +0100 Subject: [PATCH 79/79] seabios: update binaries to 1.15.0 Signed-off-by: Gerd Hoffmann --- pc-bios/bios-256k.bin | Bin 262144 -> 262144 bytes pc-bios/bios-microvm.bin | Bin 131072 -> 131072 bytes pc-bios/bios.bin | Bin 131072 -> 131072 bytes pc-bios/vgabios-ati.bin | Bin 39424 -> 39424 bytes pc-bios/vgabios-bochs-display.bin | Bin 28672 -> 28672 bytes pc-bios/vgabios-cirrus.bin | Bin 39424 -> 39424 bytes pc-bios/vgabios-qxl.bin | Bin 39424 -> 39424 bytes pc-bios/vgabios-ramfb.bin | Bin 28672 -> 28672 bytes pc-bios/vgabios-stdvga.bin | Bin 39424 -> 39424 bytes pc-bios/vgabios-virtio.bin | Bin 39424 -> 39424 bytes pc-bios/vgabios-vmware.bin | Bin 39424 -> 39424 bytes pc-bios/vgabios.bin | Bin 38912 -> 38912 bytes 12 files changed, 0 insertions(+), 0 deletions(-) diff --git a/pc-bios/bios-256k.bin b/pc-bios/bios-256k.bin index dea01da468932e67251e9ca3d443ec91d870a2ec..26f863b60926cb5dc768cff39fe944c9d297de80 100644 GIT binary patch delta 135 zcmZo@5NH6R7RDB)EzBu_InG7-#l;GShI&SNhPsBD3Q3uHr6rj;#a0SssYS(^`FRRP zddB9u#(HVV#-xAioGno9g%LOq%S_=TJy)8xn delta 105 zcmZo@5NH6R7RDB)EzBu_)3XAZ<+)7tjC9TP(vpo$rauf}7S=6F&CxZ~Gc?gN&^0pG zO*b=1Gd537HZ?X#Gt@08N=+)w%qh_;OwBFT%P&fw{?Lt4e4>ELbe|w*k!hjKEZY@= Im>;YK0D%@DXaE2J diff --git a/pc-bios/bios-microvm.bin b/pc-bios/bios-microvm.bin index ca6375d65c9d0b77dda0da82f6a0575d7c800f00..ddeb24391d158c7b4625674ba23151e70032339b 100644 GIT binary patch delta 125 zcmZo@;AjA%EsQM-Gn|X^i;EQu4fTxl40R1P6_PUZN=q_ximepNQj3Z+^Yavp^o-4Q zjrG!!jZGQSCLqJ2)Er$yJwsDH16>2%bfc6MlO)R|<1`Bs1Kon6)TGkPoD#jl)Z9|N R{G#;f2bMF6EL+4F2LMWlDu4h0 delta 99 zcmZo@;AjA%EsQM-r*|!6l=m^!GtxEFOG`F3VMv>R4vSKAbPe?kP4oRF-$J-)} diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin index e9fa99f006b74fa2c835dacf5ba8fb3c6825f426..6e6cde8c7fa722f28651e884a4c80573563baacb 100644 GIT binary patch delta 125 zcmZo@;AjA%EsQMj+0I4z#l;GShI&SNhPsBD3Q3uHr6rj;#a0SssYS(^`FRRPddB9u z#(HVV#--PM3#)%66@7F1` delta 86 zcmZo@;AjA%EsQMj)4Adq<+)7tjC9TP(vpo$rYj~f3hNi8=I9#g8Jg%B=o*>prkk0h o8Jj03n;ILW8R`}kr6!eT=9K6arskIFLNy&KtMXXZE;l*8&B^#SEq)kAEMX5QuhI)pkdIq`%y6HwKDJDslNycdwCI-3%MX5=p XnK>nTg{irvdih1^3=B*x69WwZz>+JV delta 103 zcmZqJ!ql*Zi9K|c@5>LNDI3{iXHL$VDer5lXQXSUmzHd7!jLur9TuhL=o;!7n&=tm t8ky^+o0+5;nJ}8GCY5I9l;{l*8&B^#SEq)kAEMX5QuhI)pkdIq`%y6HwKDJDslNycdwCI-3%MX5=p anK>nTg{irvdih1^3=B*xn-9iKU<3f#i7aaX delta 105 zcmZqJ!ql*Zi9K|c@5_+D2OHV{PM^#*L*Ca^&q&uyFD=>FgduGLIxI@f(KXaFG|@BA vH8R&tH#12yHcw7AH8w~y)Ga7VO)AaIDbXuT%`Mf-FG^=%V%dB!ZUQ3!9a$w? diff --git a/pc-bios/vgabios-qxl.bin b/pc-bios/vgabios-qxl.bin index 420f9ed3319025db97dd895ae574c0ee8aa41433..0cc20678a3faf187c6f5e3a83560e9f1a64dc986 100644 GIT binary patch delta 131 zcmZqJ!ql*Zi9K|c@5{HLw>Glxosr{QlwVw|U}&gkq-UsWsHu>YnO9npnNw_~P?lO$ zoSC1eV5Dbku4}B9mTYXwkTwAs7NzFs8tNIE>KW)7=%yQ`q?jaGCK;z$m>B356s0DW ZX6BUW6{hBv>g5-uGcYi*Om2+700276EqVX| delta 104 zcmZqJ!ql*Zi9K|c@5{HL8#l7=oiX{;40&HuJtJK+y|iRw6Na=2=&&d?N7qo#&_vHb u*T`Hq-OMD-*gQGe)Yu@+P`98cHK{Z+r$nzXHMdkRzbKu7iDhzQ`~?6>XC^8D diff --git a/pc-bios/vgabios-ramfb.bin b/pc-bios/vgabios-ramfb.bin index b9b2e230a5d568112dab419a67cfb8e32d9742d5..a7c5ae7c8f5e99a172c4639d4ec37df7d884e856 100644 GIT binary patch delta 135 zcmZp8z}WDBkv(*k#mmDsijx_g#W%_w%gb>t$}cWfFf`ON(lgXG)Ko~y%quO)%qg}~ zC`&CW&dkqKFw!$N*EQBlOExxTNSlBRi&ArR4fPC7^$c_kbkmJeQcRL8lZ?|WObm1j dic*tGGjmGx3R81S_413-85o#YCO5io003&PEo%S( delta 108 zcmZp8z}WDBkv(*k#mmDsKPEFei*J-WmN)rTp1iNAo{_GZURtuT2}9ZhbXb&{qid*V yXrgDJYh)uUzEewWosr{QlwVw|U}&gkq-UsWsHu>YnO9npnNw_~P?lO$ zoSC1eV5Dbku4}B9mTYXwkTwAs7NzFs8tNIE>KW)7=%yQ`q?jaGCK;z$m>B356s0DW ZX6BUW6{hBv>g5-uGcYi*Om2+7001zjEo1-y delta 104 zcmZqJ!ql*Zi9K|c@5{HLvp2HuoiX{;40&HuJtJK+y|iRw6Na=2=&&d?N7qo#&_vHb u*T`Hq-OMD-*gQGe)Yu@+P`98cHK{Z+r$nzXHMdkRzbKu7iDhzQ`~?6(l_nGb diff --git a/pc-bios/vgabios-virtio.bin b/pc-bios/vgabios-virtio.bin index c00414ab835a0a1b1a9dec207626a352eee48e91..806647a009fb64645adc7054f21cbd200d4d6f1a 100644 GIT binary patch delta 131 zcmZqJ!ql*Zi9K|c@5{HL`!=%gosr{QlwVw|U}&gkq-UsWsHu>YnO9npnNw_~P?lO$ zoSC1eV5Dbku4}B9mTYXwkTwAs7NzFs8tNIE>KW)7=%yQ`q?jaGCK;z$m>B356s0DW ZX6BUW6{hBv>g5-uGcYi*Om2+7001rHEnWZs delta 104 zcmZqJ!ql*Zi9K|c@5{HLQ#Z2joiX{;40&HuJtJK+y|iRw6Na=2=&&d?N7qo#&_vHb u*T`Hq-OMD-*gQGe)Yu@+P`98cHK{Z+r$nzXHMdkRzbKu7iDhzQ`~?6%b0!V| diff --git a/pc-bios/vgabios-vmware.bin b/pc-bios/vgabios-vmware.bin index 5454aceda8b8ddae807bb7ac245a4c7eec924206..39e3093667d608a34891ded7745af9ab266c38d1 100644 GIT binary patch delta 131 zcmZqJ!ql*Zi9K|c@5{HLi5uDX&d6~t$}cWfFf`ON(lgXG)Ko~y%quO)%qg}~C`&CW z&dkqKFw!$N*EQBlOExxTNSlBRi&ArR4fPC7^$c_kbkmJeQcRL8lZ?|WObm1jic*tG ZGjmGx3R81S_413-85o#YCO5`k00098Edc-k delta 104 zcmZqJ!ql*Zi9K|c@5{HL78}|3&X{~^hP)uUzEu93NJx|vCuv3YW`sj)$tp>9D@YEo%tPKjP&YHq1seo;CD6ARGf4FK;UC(r-@