aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml7
-rw-r--r--.gitlab-ci.d/crossbuilds.yml15
-rw-r--r--.gitlab-ci.yml43
-rw-r--r--MAINTAINERS1
-rw-r--r--blockdev.c6
-rwxr-xr-xconfigure6
-rw-r--r--docs/devel/style.rst46
-rw-r--r--docs/devel/tcg-plugins.rst5
-rw-r--r--include/sysemu/arch_init.h9
-rw-r--r--linux-user/riscv/cpu_loop.c5
-rwxr-xr-xscripts/kernel-doc3
-rw-r--r--semihosting/arm-compat-semi.c62
-rw-r--r--softmmu/qdev-monitor.c65
-rwxr-xr-xtests/qemu-iotests/0402
-rwxr-xr-xtests/qemu-iotests/05112
-rw-r--r--tests/qemu-iotests/051.out2
-rw-r--r--tests/qemu-iotests/051.pc.out2
-rwxr-xr-xtests/qemu-iotests/0684
-rwxr-xr-xtests/qemu-iotests/0933
-rwxr-xr-xtests/qemu-iotests/1273
-rwxr-xr-xtests/qemu-iotests/1399
-rwxr-xr-xtests/qemu-iotests/18213
-rwxr-xr-xtests/qemu-iotests/2384
-rwxr-xr-xtests/qemu-iotests/24010
-rwxr-xr-xtests/qemu-iotests/2566
-rwxr-xr-xtests/qemu-iotests/2574
-rwxr-xr-xtests/qemu-iotests/3074
-rw-r--r--tests/qemu-iotests/common.rc13
-rw-r--r--tests/qemu-iotests/iotests.py10
-rw-r--r--tests/qemu-iotests/testenv.py1
-rw-r--r--tests/tcg/Makefile.target3
-rw-r--r--tests/tcg/aarch64/Makefile.target18
-rw-r--r--tests/tcg/aarch64/semicall.h18
-rw-r--r--tests/tcg/arm/Makefile.target22
-rw-r--r--tests/tcg/arm/semicall.h15
-rw-r--r--tests/tcg/arm/semihosting.c26
-rw-r--r--tests/tcg/multiarch/Makefile.target31
-rw-r--r--tests/tcg/multiarch/arm-compat-semi/semiconsole.c (renamed from tests/tcg/arm/semiconsole.c)2
-rw-r--r--tests/tcg/multiarch/arm-compat-semi/semihosting.c82
-rw-r--r--tests/tcg/riscv64/semicall.h22
-rw-r--r--tests/unit/test-cutils.c171
-rw-r--r--tools/virtiofsd/fuse_lowlevel.c1
-rw-r--r--util/cutils.c33
43 files changed, 548 insertions, 271 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index bc40a0550d..f53c519447 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -3,7 +3,7 @@ env:
freebsd_12_task:
freebsd_instance:
- image_family: freebsd-12-1
+ image_family: freebsd-12-2
cpu: 8
memory: 8G
install_script:
@@ -13,7 +13,10 @@ freebsd_12_task:
script:
- mkdir build
- cd build
- - ../configure --enable-werror || { cat config.log meson-logs/meson-log.txt; exit 1; }
+ # TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
+ # See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
+ - ../configure --enable-werror --disable-gnutls
+ || { cat config.log meson-logs/meson-log.txt; exit 1; }
- gmake -j$(sysctl -n hw.ncpu)
- gmake -j$(sysctl -n hw.ncpu) check V=1
diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml
index d5098c986b..2d95784ed5 100644
--- a/.gitlab-ci.d/crossbuilds.yml
+++ b/.gitlab-ci.d/crossbuilds.yml
@@ -6,10 +6,10 @@
- mkdir build
- cd build
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
- ../configure --enable-werror $QEMU_CONFIGURE_OPTS --disable-user
- --target-list-exclude="arm-softmmu cris-softmmu i386-softmmu
- microblaze-softmmu mips-softmmu mipsel-softmmu mips64-softmmu
- ppc-softmmu sh4-softmmu xtensa-softmmu"
+ ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
+ --disable-user --target-list-exclude="arm-softmmu cris-softmmu
+ i386-softmmu microblaze-softmmu mips-softmmu mipsel-softmmu
+ mips64-softmmu ppc-softmmu sh4-softmmu xtensa-softmmu"
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
# Job to cross-build specific accelerators.
@@ -25,8 +25,8 @@
- mkdir build
- cd build
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
- ../configure --enable-werror $QEMU_CONFIGURE_OPTS --disable-tools
- --enable-${ACCEL:-kvm} $ACCEL_CONFIGURE_OPTS
+ ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
+ --disable-tools --enable-${ACCEL:-kvm} $ACCEL_CONFIGURE_OPTS
- make -j$(expr $(nproc) + 1) all check-build
.cross_user_build_job:
@@ -36,7 +36,8 @@
- mkdir build
- cd build
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
- ../configure --enable-werror $QEMU_CONFIGURE_OPTS --disable-system
+ ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
+ --disable-system
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
cross-armel-system:
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f65cb11c4d..3480d79db3 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -23,9 +23,9 @@ include:
- cd build
- if test -n "$TARGETS";
then
- ../configure --enable-werror $CONFIGURE_ARGS --target-list="$TARGETS" ;
+ ../configure --enable-werror --disable-docs $CONFIGURE_ARGS --target-list="$TARGETS" ;
else
- ../configure --enable-werror $CONFIGURE_ARGS ;
+ ../configure --enable-werror --disable-docs $CONFIGURE_ARGS ;
fi || { cat config.log meson-logs/meson-log.txt && exit 1; }
- if test -n "$LD_JOBS";
then
@@ -87,7 +87,7 @@ build-system-alpine:
TARGETS: aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu
moxie-softmmu microblazeel-softmmu mips64el-softmmu
MAKE_CHECK_ARGS: check-build
- CONFIGURE_ARGS: --enable-docs
+ CONFIGURE_ARGS: --enable-docs --enable-trace-backends=log,simple,syslog
artifacts:
expire_in: 2 days
paths:
@@ -119,7 +119,7 @@ build-system-ubuntu:
job: amd64-ubuntu2004-container
variables:
IMAGE: ubuntu2004
- CONFIGURE_ARGS: --enable-fdt=system --enable-slirp=system
+ CONFIGURE_ARGS: --enable-docs --enable-fdt=system --enable-slirp=system
TARGETS: aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu
moxie-softmmu microblazeel-softmmu mips64el-softmmu
MAKE_CHECK_ARGS: check-build
@@ -502,6 +502,7 @@ build-cfi-aarch64:
--enable-safe-stack --enable-slirp=git
TARGETS: aarch64-softmmu
MAKE_CHECK_ARGS: check-build
+ timeout: 70m
artifacts:
expire_in: 2 days
paths:
@@ -538,6 +539,7 @@ build-cfi-ppc64-s390x:
--enable-safe-stack --enable-slirp=git
TARGETS: ppc64-softmmu s390x-softmmu
MAKE_CHECK_ARGS: check-build
+ timeout: 70m
artifacts:
expire_in: 2 days
paths:
@@ -574,6 +576,7 @@ build-cfi-x86_64:
--enable-safe-stack --enable-slirp=git
TARGETS: x86_64-softmmu
MAKE_CHECK_ARGS: check-build
+ timeout: 70m
artifacts:
expire_in: 2 days
paths:
@@ -604,8 +607,8 @@ tsan-build:
job: amd64-ubuntu2004-container
variables:
IMAGE: ubuntu2004
- CONFIGURE_ARGS: --enable-tsan --cc=clang-10 --cxx=clang++-10 --disable-docs
- --enable-fdt=system --enable-slirp=system
+ CONFIGURE_ARGS: --enable-tsan --cc=clang-10 --cxx=clang++-10
+ --enable-trace-backends=ust --enable-fdt=system --enable-slirp=system
TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
MAKE_CHECK_ARGS: bench V=1
@@ -616,7 +619,7 @@ build-deprecated:
job: amd64-debian-user-cross-container
variables:
IMAGE: debian-all-test-cross
- CONFIGURE_ARGS: --disable-docs --disable-tools
+ CONFIGURE_ARGS: --disable-tools
MAKE_CHECK_ARGS: build-tcg
TARGETS: ppc64abi32-linux-user lm32-softmmu unicore32-softmmu
artifacts:
@@ -702,6 +705,7 @@ build-coroutine-sigaltstack:
variables:
IMAGE: ubuntu2004
CONFIGURE_ARGS: --with-coroutine=sigaltstack --disable-tcg
+ --enable-trace-backends=ftrace
MAKE_CHECK_ARGS: check-unit
# Most jobs test latest gcrypt or nettle builds
@@ -739,31 +743,6 @@ crypto-only-gnutls:
MAKE_CHECK_ARGS: check
-# We don't need to exercise every backend with every front-end
-build-trace-multi-user:
- <<: *native_build_job_definition
- needs:
- job: amd64-ubuntu2004-container
- variables:
- IMAGE: ubuntu2004
- CONFIGURE_ARGS: --enable-trace-backends=log,simple,syslog --disable-system
-
-build-trace-ftrace-system:
- <<: *native_build_job_definition
- needs:
- job: amd64-ubuntu2004-container
- variables:
- IMAGE: ubuntu2004
- CONFIGURE_ARGS: --enable-trace-backends=ftrace --target-list=x86_64-softmmu
-
-build-trace-ust-system:
- <<: *native_build_job_definition
- needs:
- job: amd64-ubuntu2004-container
- variables:
- IMAGE: ubuntu2004
- CONFIGURE_ARGS: --enable-trace-backends=ust --target-list=x86_64-softmmu
-
# Check our reduced build configurations
build-without-default-devices:
<<: *native_build_job_definition
diff --git a/MAINTAINERS b/MAINTAINERS
index 10ed6d7624..554be84b32 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3286,6 +3286,7 @@ M: Alex Bennée <alex.bennee@linaro.org>
S: Maintained
F: semihosting/
F: include/semihosting/
+F: tests/tcg/multiarch/arm-compat-semi/
Multi-process QEMU
M: Elena Ufimtseva <elena.ufimtseva@oracle.com>
diff --git a/blockdev.c b/blockdev.c
index 621cc3b7c4..a57590aae4 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -962,11 +962,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type,
QemuOpts *devopts;
devopts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
&error_abort);
- if (arch_type == QEMU_ARCH_S390X) {
- qemu_opt_set(devopts, "driver", "virtio-blk-ccw", &error_abort);
- } else {
- qemu_opt_set(devopts, "driver", "virtio-blk-pci", &error_abort);
- }
+ qemu_opt_set(devopts, "driver", "virtio-blk", &error_abort);
qemu_opt_set(devopts, "drive", qdict_get_str(bs_opts, "id"),
&error_abort);
}
diff --git a/configure b/configure
index edf9dc8985..535e6a9269 100755
--- a/configure
+++ b/configure
@@ -4779,9 +4779,9 @@ if test "$int128" = "yes"; then
int main(void)
{
unsigned __int128 x = 0, y = 0;
- y = __atomic_load_16(&x, 0);
- __atomic_store_16(&x, y, 0);
- __atomic_compare_exchange_16(&x, &y, x, 0, 0, 0);
+ y = __atomic_load(&x, 0);
+ __atomic_store(&x, y, 0);
+ __atomic_compare_exchange(&x, &y, x, 0, 0, 0);
return 0;
}
EOF
diff --git a/docs/devel/style.rst b/docs/devel/style.rst
index 8b0bdb3570..260e3263fa 100644
--- a/docs/devel/style.rst
+++ b/docs/devel/style.rst
@@ -385,17 +385,37 @@ avoided.
Low level memory management
===========================
-Use of the malloc/free/realloc/calloc/valloc/memalign/posix_memalign
+Use of the ``malloc/free/realloc/calloc/valloc/memalign/posix_memalign``
APIs is not allowed in the QEMU codebase. Instead of these routines,
-use the GLib memory allocation routines g_malloc/g_malloc0/g_new/
-g_new0/g_realloc/g_free or QEMU's qemu_memalign/qemu_blockalign/qemu_vfree
-APIs.
-
-Please note that g_malloc will exit on allocation failure, so there
-is no need to test for failure (as you would have to with malloc).
-Calling g_malloc with a zero size is valid and will return NULL.
-
-Prefer g_new(T, n) instead of g_malloc(sizeof(T) ``*`` n) for the following
+use the GLib memory allocation routines
+``g_malloc/g_malloc0/g_new/g_new0/g_realloc/g_free``
+or QEMU's ``qemu_memalign/qemu_blockalign/qemu_vfree`` APIs.
+
+Please note that ``g_malloc`` will exit on allocation failure, so
+there is no need to test for failure (as you would have to with
+``malloc``). Generally using ``g_malloc`` on start-up is fine as the
+result of a failure to allocate memory is going to be a fatal exit
+anyway. There may be some start-up cases where failing is unreasonable
+(for example speculatively loading a large debug symbol table).
+
+Care should be taken to avoid introducing places where the guest could
+trigger an exit by causing a large allocation. For small allocations,
+of the order of 4k, a failure to allocate is likely indicative of an
+overloaded host and allowing ``g_malloc`` to ``exit`` is a reasonable
+approach. However for larger allocations where we could realistically
+fall-back to a smaller one if need be we should use functions like
+``g_try_new`` and check the result. For example this is valid approach
+for a time/space trade-off like ``tlb_mmu_resize_locked`` in the
+SoftMMU TLB code.
+
+If the lifetime of the allocation is within the function and there are
+multiple exist paths you can also improve the readability of the code
+by using ``g_autofree`` and related annotations. See :ref:`autofree-ref`
+for more details.
+
+Calling ``g_malloc`` with a zero size is valid and will return NULL.
+
+Prefer ``g_new(T, n)`` instead of ``g_malloc(sizeof(T) * n)`` for the following
reasons:
* It catches multiplication overflowing size_t;
@@ -409,8 +429,8 @@ Declarations like
are acceptable, though.
-Memory allocated by qemu_memalign or qemu_blockalign must be freed with
-qemu_vfree, since breaking this will cause problems on Win32.
+Memory allocated by ``qemu_memalign`` or ``qemu_blockalign`` must be freed with
+``qemu_vfree``, since breaking this will cause problems on Win32.
String manipulation
===================
@@ -485,6 +505,8 @@ In addition, QEMU assumes that the compiler does not use the latitude
given in C99 and C11 to treat aspects of signed '<<' as undefined, as
documented in the GNU Compiler Collection manual starting at version 4.0.
+.. _autofree-ref:
+
Automatic memory deallocation
=============================
diff --git a/docs/devel/tcg-plugins.rst b/docs/devel/tcg-plugins.rst
index 39ce86ed96..18c6581d85 100644
--- a/docs/devel/tcg-plugins.rst
+++ b/docs/devel/tcg-plugins.rst
@@ -63,6 +63,11 @@ valid during the lifetime of the callback so it is important that any
information that is needed is extracted during the callback and saved
by the plugin.
+API
+===
+
+.. kernel-doc:: include/qemu/qemu-plugin.h
+
Usage
=====
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 54f069d491..16da279696 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -35,4 +35,13 @@ extern const uint32_t arch_type;
int kvm_available(void);
int xen_available(void);
+/* default virtio transport per architecture */
+#define QEMU_ARCH_VIRTIO_PCI (QEMU_ARCH_ALPHA | QEMU_ARCH_ARM | \
+ QEMU_ARCH_HPPA | QEMU_ARCH_I386 | \
+ QEMU_ARCH_MIPS | QEMU_ARCH_PPC | \
+ QEMU_ARCH_RISCV | QEMU_ARCH_SH4 | \
+ QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA)
+#define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X)
+#define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K)
+
#endif
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 6767f941e8..74a9628dc9 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -135,4 +135,9 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
error_report("Incompatible ELF: RVE cpu requires RVE ABI binary");
exit(EXIT_FAILURE);
}
+
+ ts->stack_base = info->start_stack;
+ ts->heap_base = info->brk;
+ /* This will be filled in on the first SYS_HEAPINFO call. */
+ ts->heap_limit = 0;
}
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 4b19851b2d..240923d509 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1745,6 +1745,9 @@ sub dump_function($$) {
)+
\)\)\s+//x;
+ # Strip QEMU specific compiler annotations
+ $prototype =~ s/QEMU_[A-Z_]+ +//;
+
# Yes, this truly is vile. We are looking for:
# 1. Return type (may be nothing if we're looking at a macro)
# 2. Function name
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 94950b6c56..fe079ca93a 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -767,15 +767,28 @@ static const GuestFDFunctions guestfd_fns[] = {
},
};
-/* Read the input value from the argument block; fail the semihosting
- * call if the memory read fails.
+/*
+ * Read the input value from the argument block; fail the semihosting
+ * call if the memory read fails. Eventually we could use a generic
+ * CPUState helper function here.
*/
-#ifdef TARGET_ARM
+static inline bool is_64bit_semihosting(CPUArchState *env)
+{
+#if defined(TARGET_ARM)
+ return is_a64(env);
+#elif defined(TARGET_RISCV)
+ return !riscv_cpu_is_32bit(env);
+#else
+#error un-handled architecture
+#endif
+}
+
+
#define GET_ARG(n) do { \
- if (is_a64(env)) { \
+ if (is_64bit_semihosting(env)) { \
if (get_user_u64(arg ## n, args + (n) * 8)) { \
errno = EFAULT; \
- return set_swi_errno(cs, -1); \
+ return set_swi_errno(cs, -1); \
} \
} else { \
if (get_user_u32(arg ## n, args + (n) * 4)) { \
@@ -786,41 +799,10 @@ static const GuestFDFunctions guestfd_fns[] = {
} while (0)
#define SET_ARG(n, val) \
- (is_a64(env) ? \
+ (is_64bit_semihosting(env) ? \
put_user_u64(val, args + (n) * 8) : \
put_user_u32(val, args + (n) * 4))
-#endif
-#ifdef TARGET_RISCV
-
-/*
- * get_user_ual is defined as get_user_u32 in softmmu-semi.h,
- * we need a macro that fetches a target_ulong
- */
-#define get_user_utl(arg, p) \
- ((sizeof(target_ulong) == 8) ? \
- get_user_u64(arg, p) : \
- get_user_u32(arg, p))
-
-/*
- * put_user_ual is defined as put_user_u32 in softmmu-semi.h,
- * we need a macro that stores a target_ulong
- */
-#define put_user_utl(arg, p) \
- ((sizeof(target_ulong) == 8) ? \
- put_user_u64(arg, p) : \
- put_user_u32(arg, p))
-
-#define GET_ARG(n) do { \
- if (get_user_utl(arg ## n, args + (n) * sizeof(target_ulong))) { \
- errno = EFAULT; \
- return set_swi_errno(cs, -1); \
- } \
- } while (0)
-
-#define SET_ARG(n, val) \
- put_user_utl(val, args + (n) * sizeof(target_ulong))
-#endif
/*
* Do a semihosting call.
@@ -1232,7 +1214,11 @@ target_ulong do_common_semihosting(CPUState *cs)
for (i = 0; i < ARRAY_SIZE(retvals); i++) {
bool fail;
- fail = SET_ARG(i, retvals[i]);
+ if (is_64bit_semihosting(env)) {
+ fail = put_user_u64(retvals[i], arg0 + i * 8);
+ } else {
+ fail = put_user_u32(retvals[i], arg0 + i * 4);
+ }
if (fail) {
/* Couldn't write back to argument block */
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index 8dc656becc..a9955b97a0 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -60,34 +60,43 @@ static const QDevAlias qdev_alias_table[] = {
{ "ES1370", "es1370" }, /* -soundhw name */
{ "ich9-ahci", "ahci" },
{ "lsi53c895a", "lsi" },
- { "virtio-9p-ccw", "virtio-9p", QEMU_ARCH_S390X },
- { "virtio-9p-pci", "virtio-9p", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-balloon-ccw", "virtio-balloon", QEMU_ARCH_S390X },
- { "virtio-balloon-pci", "virtio-balloon",
- QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-blk-ccw", "virtio-blk", QEMU_ARCH_S390X },
- { "virtio-blk-pci", "virtio-blk", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-gpu-ccw", "virtio-gpu", QEMU_ARCH_S390X },
- { "virtio-gpu-pci", "virtio-gpu", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-input-host-ccw", "virtio-input-host", QEMU_ARCH_S390X },
- { "virtio-input-host-pci", "virtio-input-host",
- QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-iommu-pci", "virtio-iommu", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-keyboard-ccw", "virtio-keyboard", QEMU_ARCH_S390X },
- { "virtio-keyboard-pci", "virtio-keyboard",
- QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-mouse-ccw", "virtio-mouse", QEMU_ARCH_S390X },
- { "virtio-mouse-pci", "virtio-mouse", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-net-ccw", "virtio-net", QEMU_ARCH_S390X },
- { "virtio-net-pci", "virtio-net", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-rng-ccw", "virtio-rng", QEMU_ARCH_S390X },
- { "virtio-rng-pci", "virtio-rng", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-scsi-ccw", "virtio-scsi", QEMU_ARCH_S390X },
- { "virtio-scsi-pci", "virtio-scsi", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-serial-ccw", "virtio-serial", QEMU_ARCH_S390X },
- { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
- { "virtio-tablet-ccw", "virtio-tablet", QEMU_ARCH_S390X },
- { "virtio-tablet-pci", "virtio-tablet", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
+ { "virtio-9p-device", "virtio-9p", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-9p-ccw", "virtio-9p", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-9p-pci", "virtio-9p", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-balloon-device", "virtio-balloon", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-balloon-ccw", "virtio-balloon", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-balloon-pci", "virtio-balloon", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-blk-device", "virtio-blk", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-blk-ccw", "virtio-blk", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-blk-pci", "virtio-blk", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-gpu-device", "virtio-gpu", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-gpu-ccw", "virtio-gpu", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-gpu-pci", "virtio-gpu", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-input-host-device", "virtio-input-host", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-input-host-ccw", "virtio-input-host", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-input-host-pci", "virtio-input-host", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-iommu-pci", "virtio-iommu", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-keyboard-device", "virtio-keyboard", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-keyboard-ccw", "virtio-keyboard", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-keyboard-pci", "virtio-keyboard", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-mouse-device", "virtio-mouse", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-mouse-ccw", "virtio-mouse", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-mouse-pci", "virtio-mouse", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-net-device", "virtio-net", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-net-ccw", "virtio-net", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-net-pci", "virtio-net", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-rng-device", "virtio-rng", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-rng-ccw", "virtio-rng", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-rng-pci", "virtio-rng", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-scsi-device", "virtio-scsi", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-scsi-ccw", "virtio-scsi", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-scsi-pci", "virtio-scsi", QEMU_ARCH_VIRTIO_PCI },
+ { "virtio-serial-device", "virtio-serial", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-serial-ccw", "virtio-serial", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_VIRTIO_PCI},
+ { "virtio-tablet-device", "virtio-tablet", QEMU_ARCH_VIRTIO_MMIO },
+ { "virtio-tablet-ccw", "virtio-tablet", QEMU_ARCH_VIRTIO_CCW },
+ { "virtio-tablet-pci", "virtio-tablet", QEMU_ARCH_VIRTIO_PCI },
{ }
};
diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
index 336ff7c4f2..ba7cb34ce8 100755
--- a/tests/qemu-iotests/040
+++ b/tests/qemu-iotests/040
@@ -89,7 +89,7 @@ class TestSingleDrive(ImageCommitTestCase):
qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', backing_img)
qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
self.vm = iotests.VM().add_drive(test_img, "node-name=top,backing.node-name=mid,backing.backing.node-name=base", interface="none")
- self.vm.add_device(iotests.get_virtio_scsi_device())
+ self.vm.add_device('virtio-scsi')
self.vm.add_device("scsi-hd,id=scsi0,drive=drive0")
self.vm.launch()
self.has_quit = False
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
index f92161d8ef..333cc81818 100755
--- a/tests/qemu-iotests/051
+++ b/tests/qemu-iotests/051
@@ -119,17 +119,7 @@ echo
echo === Device without drive ===
echo
-case "$QEMU_DEFAULT_MACHINE" in
- s390-ccw-virtio)
- virtio_scsi=virtio-scsi-ccw
- ;;
- *)
- virtio_scsi=virtio-scsi-pci
- ;;
-esac
-
-run_qemu -device $virtio_scsi -device scsi-hd |
- sed -e "s/$virtio_scsi/VIRTIO_SCSI/"
+run_qemu -device virtio-scsi -device scsi-hd
echo
echo === Overriding backing file ===
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index de4771bcb3..437053c839 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -72,7 +72,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,node-name=foo#12: Invalid node name
=== Device without drive ===
-Testing: -device VIRTIO_SCSI -device scsi-hd
+Testing: -device virtio-scsi -device scsi-hd
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device scsi-hd: drive property not set
diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out
index a28e3fc124..e95bd42b8d 100644
--- a/tests/qemu-iotests/051.pc.out
+++ b/tests/qemu-iotests/051.pc.out
@@ -72,7 +72,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,node-name=foo#12: Invalid node-name: 'fo
=== Device without drive ===
-Testing: -device VIRTIO_SCSI -device scsi-hd
+Testing: -device virtio-scsi -device scsi-hd
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device scsi-hd: drive property not set
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
index 03e03508a6..54e49c8ffa 100755
--- a/tests/qemu-iotests/068
+++ b/tests/qemu-iotests/068
@@ -49,11 +49,9 @@ IMG_SIZE=128K
case "$QEMU_DEFAULT_MACHINE" in
s390-ccw-virtio)
platform_parm="-no-shutdown"
- hba=virtio-scsi-ccw
;;
*)
platform_parm=""
- hba=virtio-scsi-pci
;;
esac
@@ -61,7 +59,7 @@ _qemu()
{
$QEMU $platform_parm -nographic -monitor stdio -serial none \
-drive if=none,id=drive0,file="$TEST_IMG",format="$IMGFMT" \
- -device $hba,id=hba0 \
+ -device virtio-scsi,id=hba0 \
-device scsi-hd,drive=drive0 \
"$@" |\
_filter_qemu | _filter_hmp
diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093
index 7745cb04b6..93274dc8cb 100755
--- a/tests/qemu-iotests/093
+++ b/tests/qemu-iotests/093
@@ -371,8 +371,7 @@ class ThrottleTestGroupNames(iotests.QMPTestCase):
class ThrottleTestRemovableMedia(iotests.QMPTestCase):
def setUp(self):
self.vm = iotests.VM()
- self.vm.add_device("{},id=virtio-scsi".format(
- iotests.get_virtio_scsi_device()))
+ self.vm.add_device("{},id=virtio-scsi".format('virtio-scsi'))
self.vm.launch()
def tearDown(self):
diff --git a/tests/qemu-iotests/127 b/tests/qemu-iotests/127
index 98e8e82a82..32edc3b068 100755
--- a/tests/qemu-iotests/127
+++ b/tests/qemu-iotests/127
@@ -44,7 +44,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file fuse
-_require_devices virtio-scsi scsi-hd
+_require_devices scsi-hd
+_require_one_device_of virtio-scsi-pci virtio-scsi-ccw
IMG_SIZE=64K
diff --git a/tests/qemu-iotests/139 b/tests/qemu-iotests/139
index e79b3c21fd..178b1ee230 100755
--- a/tests/qemu-iotests/139
+++ b/tests/qemu-iotests/139
@@ -26,18 +26,13 @@ import time
base_img = os.path.join(iotests.test_dir, 'base.img')
new_img = os.path.join(iotests.test_dir, 'new.img')
-if iotests.qemu_default_machine == 's390-ccw-virtio':
- default_virtio_blk = 'virtio-blk-ccw'
-else:
- default_virtio_blk = 'virtio-blk-pci'
class TestBlockdevDel(iotests.QMPTestCase):
def setUp(self):
iotests.qemu_img('create', '-f', iotests.imgfmt, base_img, '1M')
self.vm = iotests.VM()
- self.vm.add_device("{},id=virtio-scsi".format(
- iotests.get_virtio_scsi_device()))
+ self.vm.add_device("{},id=virtio-scsi".format('virtio-scsi'))
self.vm.launch()
def tearDown(self):
@@ -93,7 +88,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
self.checkBlockDriverState(node, expect_error)
# Add a device model
- def addDeviceModel(self, device, backend, driver = default_virtio_blk):
+ def addDeviceModel(self, device, backend, driver = 'virtio-blk'):
result = self.vm.qmp('device_add', id = device,
driver = driver, drive = backend)
self.assert_qmp(result, 'return', {})
diff --git a/tests/qemu-iotests/182 b/tests/qemu-iotests/182
index 55a0384c08..fcd1d796eb 100755
--- a/tests/qemu-iotests/182
+++ b/tests/qemu-iotests/182
@@ -46,26 +46,17 @@ _supported_proto file
size=32M
-case "$QEMU_DEFAULT_MACHINE" in
- s390-ccw-virtio)
- virtioblk=virtio-blk-ccw
- ;;
- *)
- virtioblk=virtio-blk-pci
- ;;
-esac
-
_make_test_img $size
echo "Starting QEMU"
_launch_qemu -drive file=$TEST_IMG,if=none,id=drive0,file.locking=on \
- -device $virtioblk,drive=drive0
+ -device virtio-blk,drive=drive0
echo
echo "Starting a second QEMU using the same image should fail"
echo 'quit' | $QEMU -nographic -monitor stdio \
-drive file=$TEST_IMG,if=none,id=drive0,file.locking=on \
- -device $virtioblk,drive=drive0 2>&1 | _filter_testdir 2>&1 |
+ -device virtio-blk,drive=drive0 2>&1 | _filter_testdir 2>&1 |
_filter_qemu |
sed -e '/falling back to POSIX file/d' \
-e '/locks can be lost unexpectedly/d'
diff --git a/tests/qemu-iotests/238 b/tests/qemu-iotests/238
index 8a10af57f1..38bd3744e6 100755
--- a/tests/qemu-iotests/238
+++ b/tests/qemu-iotests/238
@@ -26,14 +26,12 @@ from iotests import log
iotests.script_initialize()
-virtio_scsi_device = iotests.get_virtio_scsi_device()
-
vm = iotests.VM()
vm.launch()
log(vm.qmp('blockdev-add', node_name='hd0', driver='null-co', read_zeroes=True))
log(vm.qmp('object-add', qom_type='iothread', id='iothread0'))
-log(vm.qmp('device_add', id='scsi0', driver=virtio_scsi_device, iothread='iothread0'))
+log(vm.qmp('device_add', id='scsi0', driver='virtio-scsi', iothread='iothread0'))
log(vm.qmp('device_add', id='scsi-hd0', driver='scsi-hd', drive='hd0'))
log(vm.qmp('block_set_io_throttle', id='scsi-hd0', bps=0, bps_rd=0, bps_wr=0,
iops=1000, iops_rd=0, iops_wr=0, conv_keys=False))
diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240
index ab077f4ceb..9b281e1dc0 100755
--- a/tests/qemu-iotests/240
+++ b/tests/qemu-iotests/240
@@ -42,7 +42,7 @@ class TestCase(iotests.QMPTestCase):
iotests.log('==Unplug a SCSI disk and then plug it again==')
self.vm.qmp_log('blockdev-add', driver='null-co', read_zeroes=True, node_name='hd0')
self.vm.qmp_log('object-add', qom_type='iothread', id="iothread0")
- self.vm.qmp_log('device_add', id='scsi0', driver=iotests.get_virtio_scsi_device(), iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
+ self.vm.qmp_log('device_add', id='scsi0', driver='virtio-scsi', iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
self.vm.qmp_log('device_add', id='scsi-hd0', driver='scsi-hd', drive='hd0')
self.vm.qmp_log('device_del', id='scsi-hd0')
self.vm.event_wait('DEVICE_DELETED')
@@ -55,7 +55,7 @@ class TestCase(iotests.QMPTestCase):
iotests.log('==Attach two SCSI disks using the same block device and the same iothread==')
self.vm.qmp_log('blockdev-add', driver='null-co', read_zeroes=True, node_name='hd0', read_only=True)
self.vm.qmp_log('object-add', qom_type='iothread', id="iothread0")
- self.vm.qmp_log('device_add', id='scsi0', driver=iotests.get_virtio_scsi_device(), iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
+ self.vm.qmp_log('device_add', id='scsi0', driver='virtio-scsi', iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
self.vm.qmp_log('device_add', id='scsi-hd0', driver='scsi-hd', drive='hd0')
self.vm.qmp_log('device_add', id='scsi-hd1', driver='scsi-hd', drive='hd0')
@@ -73,8 +73,8 @@ class TestCase(iotests.QMPTestCase):
self.vm.qmp_log('object-add', qom_type='iothread', id="iothread0")
self.vm.qmp_log('object-add', qom_type='iothread', id="iothread1")
- self.vm.qmp_log('device_add', id='scsi0', driver=iotests.get_virtio_scsi_device(), iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
- self.vm.qmp_log('device_add', id='scsi1', driver=iotests.get_virtio_scsi_device(), iothread='iothread1', filters=[iotests.filter_qmp_virtio_scsi])
+ self.vm.qmp_log('device_add', id='scsi0', driver='virtio-scsi', iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
+ self.vm.qmp_log('device_add', id='scsi1', driver='virtio-scsi', iothread='iothread1', filters=[iotests.filter_qmp_virtio_scsi])
self.vm.qmp_log('device_add', id='scsi-hd0', driver='scsi-hd', drive='hd0', bus="scsi0.0")
self.vm.qmp_log('device_add', id='scsi-hd1', driver='scsi-hd', drive='hd0', bus="scsi1.0")
@@ -99,7 +99,7 @@ class TestCase(iotests.QMPTestCase):
self.vm.qmp_log('nbd-server-add', device='hd0')
self.vm.qmp_log('object-add', qom_type='iothread', id="iothread0")
- self.vm.qmp_log('device_add', id='scsi0', driver=iotests.get_virtio_scsi_device(), iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
+ self.vm.qmp_log('device_add', id='scsi0', driver='virtio-scsi', iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
self.vm.qmp_log('device_add', id='scsi-hd0', driver='scsi-hd', drive='hd0')
if __name__ == '__main__':
diff --git a/tests/qemu-iotests/256 b/tests/qemu-iotests/256
index 8d82a1dd86..13666813bd 100755
--- a/tests/qemu-iotests/256
+++ b/tests/qemu-iotests/256
@@ -24,6 +24,8 @@ import os
import iotests
from iotests import log
+iotests._verify_virtio_scsi_pci_or_ccw()
+
iotests.script_initialize(supported_fmts=['qcow2'])
size = 64 * 1024 * 1024
@@ -61,8 +63,8 @@ with iotests.FilePath('img0') as img0_path, \
log('--- Preparing images & VM ---\n')
vm.add_object('iothread,id=iothread0')
vm.add_object('iothread,id=iothread1')
- vm.add_device('virtio-scsi-pci,id=scsi0,iothread=iothread0')
- vm.add_device('virtio-scsi-pci,id=scsi1,iothread=iothread1')
+ vm.add_device('virtio-scsi,id=scsi0,iothread=iothread0')
+ vm.add_device('virtio-scsi,id=scsi1,iothread=iothread1')
iotests.qemu_img_create('-f', iotests.imgfmt, img0_path, str(size))
iotests.qemu_img_create('-f', iotests.imgfmt, img1_path, str(size))
vm.add_drive(img0_path, interface='none')
diff --git a/tests/qemu-iotests/257 b/tests/qemu-iotests/257
index 7cd2520829..c72c82a171 100755
--- a/tests/qemu-iotests/257
+++ b/tests/qemu-iotests/257
@@ -292,7 +292,7 @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
log('--- Preparing image & VM ---\n')
drive0 = Drive(img_path, vm=vm)
drive0.img_create(iotests.imgfmt, SIZE)
- vm.add_device("{},id=scsi0".format(iotests.get_virtio_scsi_device()))
+ vm.add_device("{},id=scsi0".format('virtio-scsi'))
vm.launch()
file_config = {
@@ -449,7 +449,7 @@ def test_backup_api():
log('--- Preparing image & VM ---\n')
drive0 = Drive(img_path, vm=vm)
drive0.img_create(iotests.imgfmt, SIZE)
- vm.add_device("{},id=scsi0".format(iotests.get_virtio_scsi_device()))
+ vm.add_device("{},id=scsi0".format('virtio-scsi'))
vm.launch()
file_config = {
diff --git a/tests/qemu-iotests/307 b/tests/qemu-iotests/307
index 9008974346..c7685347bc 100755
--- a/tests/qemu-iotests/307
+++ b/tests/qemu-iotests/307
@@ -40,13 +40,11 @@ with iotests.FilePath('image') as img, \
iotests.log('=== Launch VM ===')
- virtio_scsi_device = iotests.get_virtio_scsi_device()
-
vm.add_object('iothread,id=iothread0')
vm.add_blockdev(f'file,filename={img},node-name=file')
vm.add_blockdev(f'{iotests.imgfmt},file=file,node-name=fmt')
vm.add_blockdev('raw,file=file,node-name=ro,read-only=on')
- vm.add_device(f'id=scsi0,driver={virtio_scsi_device},iothread=iothread0')
+ vm.add_device(f'id=scsi0,driver=virtio-scsi,iothread=iothread0')
vm.launch()
vm.qmp_log('nbd-server-start',
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 65cdba5723..7f49c9716d 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -977,5 +977,18 @@ _require_devices()
done
}
+_require_one_device_of()
+{
+ available=$($QEMU -M none -device help | \
+ grep ^name | sed -e 's/^name "//' -e 's/".*$//')
+ for device
+ do
+ if echo "$available" | grep -q "$device" ; then
+ return
+ fi
+ done
+ _notrun "$* not available"
+}
+
# make sure this script returns success
true
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 90d0b62523..5af0182895 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -234,11 +234,6 @@ def qemu_io_silent_check(*args):
stderr=subprocess.STDOUT)
return exitcode == 0
-def get_virtio_scsi_device():
- if qemu_default_machine == 's390-ccw-virtio':
- return 'virtio-scsi-ccw'
- return 'virtio-scsi-pci'
-
class QemuIoInteractive:
def __init__(self, *args):
self.args = qemu_io_args_no_fmt + list(args)
@@ -1151,6 +1146,11 @@ def _verify_virtio_blk() -> None:
if 'virtio-blk' not in out:
notrun('Missing virtio-blk in QEMU binary')
+def _verify_virtio_scsi_pci_or_ccw() -> None:
+ out = qemu_pipe('-M', 'none', '-device', 'help')
+ if 'virtio-scsi-pci' not in out and 'virtio-scsi-ccw' not in out:
+ notrun('Missing virtio-scsi-pci or virtio-scsi-ccw in QEMU binary')
+
def supports_quorum():
return 'quorum' in qemu_img_pipe('--help')
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index 1fbec854c1..6d27712617 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -208,6 +208,7 @@ class TestEnv(ContextManager['TestEnv']):
('arm', 'virt'),
('aarch64', 'virt'),
('avr', 'mega2560'),
+ ('m68k', 'virt'),
('rx', 'gdbsim-r5f562n8'),
('tricore', 'tricore_testboard')
)
diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target
index 24d75a5801..cab8c6b3a2 100644
--- a/tests/tcg/Makefile.target
+++ b/tests/tcg/Makefile.target
@@ -32,6 +32,9 @@
all:
-include ../../../config-host.mak
-include ../config-$(TARGET).mak
+ifeq ($(CONFIG_USER_ONLY),y)
+-include $(SRC_PATH)/default-configs/targets/$(TARGET).mak
+endif
# for including , in command strings
COMMA := ,
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
index bf53ad0087..56e48f4b34 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -41,24 +41,6 @@ AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4
mte-%: CFLAGS += -march=armv8.5-a+memtag
endif
-# Semihosting smoke test for linux-user
-AARCH64_TESTS += semihosting
-run-semihosting: semihosting
- $(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
-
-run-plugin-semihosting-with-%:
- $(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
- -plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \
- $(call strip-plugin,$<) 2> $<.err, \
- "$< on $(TARGET_NAME) with $*")
-
-AARCH64_TESTS += semiconsole
-run-semiconsole: semiconsole
- $(call skip-test, $<, "MANUAL ONLY")
-
-run-plugin-semiconsole-with-%:
- $(call skip-test, $<, "MANUAL ONLY")
-
ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_SVE),)
# System Registers Tests
AARCH64_TESTS += sysregs
diff --git a/tests/tcg/aarch64/semicall.h b/tests/tcg/aarch64/semicall.h
new file mode 100644
index 0000000000..8a3fce35c5
--- /dev/null
+++ b/tests/tcg/aarch64/semicall.h
@@ -0,0 +1,18 @@
+/*
+ * Semihosting Tests - AArch64 helper
+ *
+ * Copyright (c) 2019
+ * Written by Alex Bennée <alex.bennee@linaro.org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+uintptr_t __semi_call(uintptr_t type, uintptr_t arg0)
+{
+ register uintptr_t t asm("x0") = type;
+ register uintptr_t a0 asm("x1") = arg0;
+ asm("hlt 0xf000"
+ : "=r" (t)
+ : "r" (t), "r" (a0));
+ return t;
+}
diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target
index ec95156562..5ab59ed6ce 100644
--- a/tests/tcg/arm/Makefile.target
+++ b/tests/tcg/arm/Makefile.target
@@ -29,37 +29,31 @@ run-fcvt: fcvt
$(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)")
$(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
+ifeq ($(CONFIG_ARM_COMPATIBLE_SEMIHOSTING),y)
+
# Semihosting smoke test for linux-user
-ARM_TESTS += semihosting
semihosting: CFLAGS += -mthumb
-run-semihosting: semihosting
- $(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
ARM_TESTS += semihosting-arm
-semihosting-arm: CFLAGS += -marm
+semihosting-arm: CFLAGS += -marm -I$(SRC_PATH)/tests/tcg/$(TARGET_NAME)
semihosting-arm: semihosting.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
run-semihosting-arm: semihosting-arm
$(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
-run-plugin-semihosting-with-%:
+run-plugin-semihosting-arm-with-%:
$(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
-plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \
$(call strip-plugin,$<) 2> $<.err, \
"$< on $(TARGET_NAME) with $*")
-ARM_TESTS += semiconsole semiconsole-arm
+ARM_TESTS += semiconsole-arm
semiconsole: CFLAGS += -mthumb
-run-semiconsole: semiconsole
- $(call skip-test, $<, "MANUAL ONLY")
-run-plugin-semiconsole-with-%:
- $(call skip-test, $<, "MANUAL ONLY")
-
-semiconsole-arm: CFLAGS += -marm
-semiconsole-arm: semiconsole.c
+semiconsole-arm: CFLAGS += -marm -I$(SRC_PATH)/tests/tcg/$(TARGET_NAME)
+semiconsole-arm: semihosting.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
run-semiconsole-arm: semiconsole-arm
@@ -68,6 +62,8 @@ run-semiconsole-arm: semiconsole-arm
run-plugin-semiconsole-arm-with-%:
$(call skip-test, $<, "MANUAL ONLY")
+endif
+
ARM_TESTS += commpage
TESTS += $(ARM_TESTS)
diff --git a/tests/tcg/arm/semicall.h b/tests/tcg/arm/semicall.h
index d4f6818192..ad8ac51310 100644
--- a/tests/tcg/arm/semicall.h
+++ b/tests/tcg/arm/semicall.h
@@ -1,5 +1,5 @@
/*
- * Semihosting Tests
+ * Semihosting Tests - ARM Helper
*
* Copyright (c) 2019
* Written by Alex Bennée <alex.bennee@linaro.org>
@@ -7,13 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-#define SYS_WRITE0 0x04
-#define SYS_READC 0x07
-#define SYS_REPORTEXC 0x18
-
uintptr_t __semi_call(uintptr_t type, uintptr_t arg0)
{
-#if defined(__arm__)
register uintptr_t t asm("r0") = type;
register uintptr_t a0 asm("r1") = arg0;
#ifdef __thumb__
@@ -23,13 +18,5 @@ uintptr_t __semi_call(uintptr_t type, uintptr_t arg0)
#endif
asm(SVC : "=r" (t)
: "r" (t), "r" (a0));
-#else
- register uintptr_t t asm("x0") = type;
- register uintptr_t a0 asm("x1") = arg0;
- asm("hlt 0xf000"
- : "=r" (t)
- : "r" (t), "r" (a0));
-#endif
-
return t;
}
diff --git a/tests/tcg/arm/semihosting.c b/tests/tcg/arm/semihosting.c
deleted file mode 100644
index 33faac9916..0000000000
--- a/tests/tcg/arm/semihosting.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * linux-user semihosting checks
- *
- * Copyright (c) 2019
- * Written by Alex Bennée <alex.bennee@linaro.org>
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-#include <stdint.h>
-#include "semicall.h"
-
-int main(int argc, char *argv[argc])
-{
-#if defined(__arm__)
- uintptr_t exit_code = 0x20026;
-#else
- uintptr_t exit_block[2] = {0x20026, 0};
- uintptr_t exit_code = (uintptr_t) &exit_block;
-#endif
-
- __semi_call(SYS_WRITE0, (uintptr_t) "Hello World");
- __semi_call(SYS_REPORTEXC, exit_code);
- /* if we get here we failed */
- return -1;
-}
diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
index abbdb2e126..a3a751723d 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -69,6 +69,37 @@ run-gdbstub-%:
endif
EXTRA_RUNS += run-gdbstub-sha1 run-gdbstub-qxfer-auxv-read
+# ARM Compatible Semi Hosting Tests
+#
+# Despite having ARM in the name we actually have several
+# architectures that implement it. We gate the tests on the feature
+# appearing in config.
+#
+ifeq ($(CONFIG_ARM_COMPATIBLE_SEMIHOSTING),y)
+VPATH += $(MULTIARCH_SRC)/arm-compat-semi
+
+# Add -I path back to TARGET_NAME for semicall.h
+semihosting: CFLAGS+=-I$(SRC_PATH)/tests/tcg/$(TARGET_NAME)
+
+run-semihosting: semihosting
+ $(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
+
+run-plugin-semihosting-with-%:
+ $(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
+ -plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \
+ $(call strip-plugin,$<) 2> $<.err, \
+ "$< on $(TARGET_NAME) with $*")
+
+semiconsole: CFLAGS+=-I$(SRC_PATH)/tests/tcg/$(TARGET_NAME)
+
+run-semiconsole: semiconsole
+ $(call skip-test, $<, "MANUAL ONLY")
+
+run-plugin-semiconsole-with-%:
+ $(call skip-test, $<, "MANUAL ONLY")
+
+TESTS += semihosting semiconsole
+endif
# Update TESTS
TESTS += $(MULTIARCH_TESTS)
diff --git a/tests/tcg/arm/semiconsole.c b/tests/tcg/multiarch/arm-compat-semi/semiconsole.c
index 6ef0bd2450..1d82efc589 100644
--- a/tests/tcg/arm/semiconsole.c
+++ b/tests/tcg/multiarch/arm-compat-semi/semiconsole.c
@@ -7,6 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
+#define SYS_READC 0x07
+
#include <stdio.h>
#include <stdint.h>
#include "semicall.h"
diff --git a/tests/tcg/multiarch/arm-compat-semi/semihosting.c b/tests/tcg/multiarch/arm-compat-semi/semihosting.c
new file mode 100644
index 0000000000..8627eee3cf
--- /dev/null
+++ b/tests/tcg/multiarch/arm-compat-semi/semihosting.c
@@ -0,0 +1,82 @@
+/*
+ * linux-user semihosting checks
+ *
+ * Copyright (c) 2019
+ * Written by Alex Bennée <alex.bennee@linaro.org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define SYS_WRITE0 0x04
+#define SYS_HEAPINFO 0x16
+#define SYS_REPORTEXC 0x18
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "semicall.h"
+
+int main(int argc, char *argv[argc])
+{
+#if UINTPTR_MAX == UINT32_MAX
+ uintptr_t exit_code = 0x20026;
+#else
+ uintptr_t exit_block[2] = {0x20026, 0};
+ uintptr_t exit_code = (uintptr_t) &exit_block;
+#endif
+ struct {
+ void *heap_base;
+ void *heap_limit;
+ void *stack_base;
+ void *stack_limit;
+ } info;
+ void *ptr_to_info = (void *) &info;
+
+ __semi_call(SYS_WRITE0, (uintptr_t) "Checking HeapInfo\n");
+
+ memset(&info, 0, sizeof(info));
+ __semi_call(SYS_HEAPINFO, (uintptr_t) &ptr_to_info);
+
+ if (info.heap_base == NULL || info.heap_limit == NULL) {
+ printf("null heap: %p -> %p\n", info.heap_base, info.heap_limit);
+ exit(1);
+ }
+
+ /* Error if heap base is above limit */
+ if ((uintptr_t) info.heap_base >= (uintptr_t) info.heap_limit) {
+ printf("heap base %p >= heap_limit %p\n",
+ info.heap_base, info.heap_limit);
+ exit(2);
+ }
+
+ if (info.stack_base == NULL || info.stack_limit) {
+ printf("null stack: %p -> %p\n", info.stack_base, info.stack_limit);
+ exit(3);
+ }
+
+ /* check our local variables are indeed inside the reported stack */
+ if (ptr_to_info > info.stack_base) {
+ printf("info appears to be above stack: %p > %p\n", ptr_to_info,
+ info.stack_base);
+ exit(4);
+ } else if (ptr_to_info < info.stack_limit) {
+ printf("info appears to be outside stack: %p < %p\n", ptr_to_info,
+ info.stack_limit);
+ exit(5);
+ }
+
+ if (ptr_to_info > info.heap_base && ptr_to_info < info.heap_limit) {
+ printf("info appears to be inside the heap: %p in %p:%p\n",
+ ptr_to_info, info.heap_base, info.heap_limit);
+ exit(6);
+ }
+
+ printf("heap: %p -> %p\n", info.heap_base, info.heap_limit);
+ printf("stack: %p -> %p\n", info.stack_base, info.stack_limit);
+
+ __semi_call(SYS_WRITE0, (uintptr_t) "Passed HeapInfo checks");
+ __semi_call(SYS_REPORTEXC, exit_code);
+ /* if we get here we failed */
+ return -1;
+}
diff --git a/tests/tcg/riscv64/semicall.h b/tests/tcg/riscv64/semicall.h
new file mode 100644
index 0000000000..f8c88f32dc
--- /dev/null
+++ b/tests/tcg/riscv64/semicall.h
@@ -0,0 +1,22 @@
+/*
+ * Semihosting Tests - RiscV64 Helper
+ *
+ * Copyright (c) 2021
+ * Written by Alex Bennée <alex.bennee@linaro.org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+uintptr_t __semi_call(uintptr_t type, uintptr_t arg0)
+{
+ register uintptr_t t asm("a0") = type;
+ register uintptr_t a0 asm("a1") = arg0;
+ asm(".option norvc\n\t"
+ ".balign 16\n\t"
+ "slli zero, zero, 0x1f\n\t"
+ "ebreak\n\t"
+ "srai zero, zero, 0x7\n\t"
+ : "=r" (t)
+ : "r" (t), "r" (a0));
+ return t;
+}
diff --git a/tests/unit/test-cutils.c b/tests/unit/test-cutils.c
index e025b54c05..98671f1ac3 100644
--- a/tests/unit/test-cutils.c
+++ b/tests/unit/test-cutils.c
@@ -378,6 +378,15 @@ static void test_qemu_strtoi_hex(void)
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
+
+ str = "0x";
+ res = 999;
+ endptr = &f;
+ err = qemu_strtoi(str, &endptr, 16, &res);
+
+ g_assert_cmpint(err, ==, 0);
+ g_assert_cmpint(res, ==, 0);
+ g_assert(endptr == str + 1);
}
static void test_qemu_strtoi_max(void)
@@ -669,6 +678,15 @@ static void test_qemu_strtoui_hex(void)
g_assert_cmpint(err, ==, 0);
g_assert_cmphex(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
+
+ str = "0x";
+ res = 999;
+ endptr = &f;
+ err = qemu_strtoui(str, &endptr, 16, &res);
+
+ g_assert_cmpint(err, ==, 0);
+ g_assert_cmphex(res, ==, 0);
+ g_assert(endptr == str + 1);
}
static void test_qemu_strtoui_max(void)
@@ -955,6 +973,15 @@ static void test_qemu_strtol_hex(void)
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
+
+ str = "0x";
+ res = 999;
+ endptr = &f;
+ err = qemu_strtol(str, &endptr, 16, &res);
+
+ g_assert_cmpint(err, ==, 0);
+ g_assert_cmpint(res, ==, 0);
+ g_assert(endptr == str + 1);
}
static void test_qemu_strtol_max(void)
@@ -1244,6 +1271,15 @@ static void test_qemu_strtoul_hex(void)
g_assert_cmpint(err, ==, 0);
g_assert_cmphex(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
+
+ str = "0x";
+ res = 999;
+ endptr = &f;
+ err = qemu_strtoul(str, &endptr, 16, &res);
+
+ g_assert_cmpint(err, ==, 0);
+ g_assert_cmphex(res, ==, 0);
+ g_assert(endptr == str + 1);
}
static void test_qemu_strtoul_max(void)
@@ -1528,6 +1564,15 @@ static void test_qemu_strtoi64_hex(void)
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
+
+ str = "0x";
+ endptr = &f;
+ res = 999;
+ err = qemu_strtoi64(str, &endptr, 16, &res);
+
+ g_assert_cmpint(err, ==, 0);
+ g_assert_cmpint(res, ==, 0);
+ g_assert(endptr == str + 1);
}
static void test_qemu_strtoi64_max(void)
@@ -1815,6 +1860,15 @@ static void test_qemu_strtou64_hex(void)
g_assert_cmpint(err, ==, 0);
g_assert_cmphex(res, ==, 0x123);
g_assert(endptr == str + strlen(str));
+
+ str = "0x";
+ endptr = &f;
+ res = 999;
+ err = qemu_strtou64(str, &endptr, 16, &res);
+
+ g_assert_cmpint(err, ==, 0);
+ g_assert_cmphex(res, ==, 0);
+ g_assert(endptr == str + 1);
}
static void test_qemu_strtou64_max(void)
@@ -1952,9 +2006,11 @@ static void test_qemu_strtosz_simple(void)
const char *str;
const char *endptr;
int err;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
str = "0";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0);
@@ -1962,6 +2018,8 @@ static void test_qemu_strtosz_simple(void)
/* Leading 0 gives decimal results, not octal */
str = "08";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 8);
@@ -1969,46 +2027,61 @@ static void test_qemu_strtosz_simple(void)
/* Leading space is ignored */
str = " 12345";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345);
g_assert(endptr == str + 6);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345);
str = "9007199254740991"; /* 2^53-1 */
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x1fffffffffffff);
g_assert(endptr == str + 16);
str = "9007199254740992"; /* 2^53 */
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x20000000000000);
g_assert(endptr == str + 16);
str = "9007199254740993"; /* 2^53+1 */
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0x20000000000001);
g_assert(endptr == str + 16);
str = "18446744073709549568"; /* 0xfffffffffffff800 (53 msbs set) */
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0xfffffffffffff800);
g_assert(endptr == str + 20);
str = "18446744073709550591"; /* 0xfffffffffffffbff */
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0xfffffffffffffbff);
g_assert(endptr == str + 20);
str = "18446744073709551615"; /* 0xffffffffffffffff */
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0xffffffffffffffff);
@@ -2020,21 +2093,27 @@ static void test_qemu_strtosz_hex(void)
const char *str;
const char *endptr;
int err;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
str = "0x0";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0);
g_assert(endptr == str + 3);
str = "0xab";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 171);
g_assert(endptr == str + 4);
str = "0xae";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 174);
@@ -2053,44 +2132,60 @@ static void test_qemu_strtosz_units(void)
const char *e = "1E";
int err;
const char *endptr;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
/* default is M */
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz_MiB(none, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, MiB);
g_assert(endptr == none + 1);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(b, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 1);
g_assert(endptr == b + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(k, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, KiB);
g_assert(endptr == k + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(m, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, MiB);
g_assert(endptr == m + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(g, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, GiB);
g_assert(endptr == g + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(t, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, TiB);
g_assert(endptr == t + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(p, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, PiB);
g_assert(endptr == p + 2);
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(e, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, EiB);
@@ -2102,9 +2197,11 @@ static void test_qemu_strtosz_float(void)
const char *str;
int err;
const char *endptr;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
str = "0.5E";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, EiB / 2);
@@ -2112,6 +2209,8 @@ static void test_qemu_strtosz_float(void)
/* For convenience, a fraction of 0 is tolerated even on bytes */
str = "1.0B";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 1);
@@ -2119,6 +2218,8 @@ static void test_qemu_strtosz_float(void)
/* An empty fraction is tolerated */
str = "1.k";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 1024);
@@ -2126,6 +2227,8 @@ static void test_qemu_strtosz_float(void)
/* For convenience, we permit values that are not byte-exact */
str = "12.345M";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, (uint64_t) (12.345 * MiB + 0.5));
@@ -2140,67 +2243,91 @@ static void test_qemu_strtosz_invalid(void)
uint64_t res = 0xbaadf00d;
str = "";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = " \t ";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "crap";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "inf";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "NaN";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
/* Fractional values require scale larger than bytes */
str = "1.1B";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "1.1";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
/* No floating point exponents */
str = "1.5e1k";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "1.5E+0k";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
/* No hex fractions */
str = "0x1.8k";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
/* No negative values */
str = "-0";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
str = "-1";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str);
}
@@ -2209,48 +2336,72 @@ static void test_qemu_strtosz_trailing(void)
const char *str;
const char *endptr;
int err;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
str = "123xxx";
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz_MiB(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 123 * MiB);
g_assert(endptr == str + 3);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
str = "1kiB";
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 1024);
g_assert(endptr == str + 2);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
str = "0x";
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 0);
g_assert(endptr == str + 1);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
str = "0.NaN";
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
+ g_assert_cmpint(res, ==, 0);
g_assert(endptr == str + 2);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
str = "123-45";
+ endptr = NULL;
+ res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 123);
g_assert(endptr == str + 3);
+ res = 0xbaadf00d;
err = qemu_strtosz(str, NULL, &res);
g_assert_cmpint(err, ==, -EINVAL);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
}
static void test_qemu_strtosz_erange(void)
@@ -2261,13 +2412,17 @@ static void test_qemu_strtosz_erange(void)
uint64_t res = 0xbaadf00d;
str = "18446744073709551616"; /* 2^64; see strtosz_simple for 2^64-1 */
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -ERANGE);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str + 20);
str = "20E";
+ endptr = NULL;
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -ERANGE);
+ g_assert_cmpint(res, ==, 0xbaadf00d);
g_assert(endptr == str + 3);
}
@@ -2276,15 +2431,19 @@ static void test_qemu_strtosz_metric(void)
const char *str;
int err;
const char *endptr;
- uint64_t res = 0xbaadf00d;
+ uint64_t res;
str = "12345k";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz_metric(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345000);
g_assert(endptr == str + 6);
str = "12.345M";
+ endptr = str;
+ res = 0xbaadf00d;
err = qemu_strtosz_metric(str, &endptr, &res);
g_assert_cmpint(err, ==, 0);
g_assert_cmpint(res, ==, 12345000);
diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c
index 1aa26c6333..58e32fc963 100644
--- a/tools/virtiofsd/fuse_lowlevel.c
+++ b/tools/virtiofsd/fuse_lowlevel.c
@@ -2450,6 +2450,7 @@ void fuse_lowlevel_help(void)
printf(
" -o allow_root allow access by root\n"
" --socket-path=PATH path for the vhost-user socket\n"
+ " --socket-group=GRNAME name of group for the vhost-user socket\n"
" --fd=FDNUM fd number of vhost-user socket\n"
" --thread-pool-size=NUM thread pool size limit (default %d)\n",
THREAD_POOL_SIZE);
diff --git a/util/cutils.c b/util/cutils.c
index c442882b88..ee908486da 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -362,7 +362,6 @@ static int do_strtosz(const char *nptr, const char **end,
}
}
- *result = val;
retval = 0;
out:
@@ -371,6 +370,9 @@ out:
} else if (*endptr) {
retval = -EINVAL;
}
+ if (retval == 0) {
+ *result = val;
+ }
return retval;
}
@@ -394,9 +396,22 @@ int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result)
* Helper function for error checking after strtol() and the like
*/
static int check_strtox_error(const char *nptr, char *ep,
- const char **endptr, int libc_errno)
+ const char **endptr, bool check_zero,
+ int libc_errno)
{
assert(ep >= nptr);
+
+ /* Windows has a bug in that it fails to parse 0 from "0x" in base 16 */
+ if (check_zero && ep == nptr && libc_errno == 0) {
+ char *tmp;
+
+ errno = 0;
+ if (strtol(nptr, &tmp, 10) == 0 && errno == 0 &&
+ (*tmp == 'x' || *tmp == 'X')) {
+ ep = tmp;
+ }
+ }
+
if (endptr) {
*endptr = ep;
}
@@ -463,7 +478,7 @@ int qemu_strtoi(const char *nptr, const char **endptr, int base,
} else {
*result = lresult;
}
- return check_strtox_error(nptr, ep, endptr, errno);
+ return check_strtox_error(nptr, ep, endptr, lresult == 0, errno);
}
/**
@@ -522,7 +537,7 @@ int qemu_strtoui(const char *nptr, const char **endptr, int base,
*result = lresult;
}
}
- return check_strtox_error(nptr, ep, endptr, errno);
+ return check_strtox_error(nptr, ep, endptr, lresult == 0, errno);
}
/**
@@ -564,7 +579,7 @@ int qemu_strtol(const char *nptr, const char **endptr, int base,
errno = 0;
*result = strtol(nptr, &ep, base);
- return check_strtox_error(nptr, ep, endptr, errno);
+ return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
}
/**
@@ -611,7 +626,7 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base,
if (errno == ERANGE) {
*result = -1;
}
- return check_strtox_error(nptr, ep, endptr, errno);
+ return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
}
/**
@@ -637,7 +652,7 @@ int qemu_strtoi64(const char *nptr, const char **endptr, int base,
QEMU_BUILD_BUG_ON(sizeof(int64_t) != sizeof(long long));
errno = 0;
*result = strtoll(nptr, &ep, base);
- return check_strtox_error(nptr, ep, endptr, errno);
+ return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
}
/**
@@ -666,7 +681,7 @@ int qemu_strtou64(const char *nptr, const char **endptr, int base,
if (errno == ERANGE) {
*result = -1;
}
- return check_strtox_error(nptr, ep, endptr, errno);
+ return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
}
/**
@@ -706,7 +721,7 @@ int qemu_strtod(const char *nptr, const char **endptr, double *result)
errno = 0;
*result = strtod(nptr, &ep);
- return check_strtox_error(nptr, ep, endptr, errno);
+ return check_strtox_error(nptr, ep, endptr, false, errno);
}
/**