Various fixes for 6.0:
- include kernel-doc API reference for plugins - fix semihosting SYS_HEAPINFO - various tweaks to improve CI runtime - more stroz fixes - fix iotest CI regressions -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmBbTIgACgkQ+9DbCVqe KkTGPQf+LqwQeJswpn6/CMpNikNWM8tGZCr/mWuArQ+7yvjkDImKzrOHFBFylCbA /A5FJ4hbeGoDJWzgQERx9iOiwHBsJ6Co3+E5qUiZnfDTyxWW4YBHOSFyBxq4RpEt t/f++CIllKQ9u0QQAJnzgmdkrp+mZedrHwkhlaZlMwT3qSzWueAoEsfsc6hkja/U lS6uIBWA31VCSh7GS/jRkYBPLA6JjJt1BR9kvcsi6d9OC45iLDe2fUzLC0CLFjnN hWliIEh8amkezp+G5IL2ciXA5y0wYMig6ZWg1+8ZknfKQS7pAka6DK9Cr6pvwFaU 8zrzF+/BqoWLi8VGm9L6kEOUgswNIQ== =zrEh -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/stsquad/tags/pull-6.0-rc0-fixed-240321-1' into staging Various fixes for 6.0: - include kernel-doc API reference for plugins - fix semihosting SYS_HEAPINFO - various tweaks to improve CI runtime - more stroz fixes - fix iotest CI regressions # gpg: Signature made Wed 24 Mar 2021 14:28:24 GMT # gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44 # gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full] # Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44 * remotes/stsquad/tags/pull-6.0-rc0-fixed-240321-1: (22 commits) gitlab: default to not building the documentation iotests: iothreads need ioeventfd iotests: test m68k with the virt machine iotests: Revert "iotests: use -ccw on s390x for 040, 139, and 182" blockdev: with -drive if=virtio, use generic virtio-blk m68k: add the virtio devices aliases qdev: define list of archs with virtio-pci or virtio-ccw gitlab: extend timeouts for CFI builds utils: Work around mingw strto*l bug with 0x utils: Tighter tests for qemu_strtosz cirrus.yml: Update the FreeBSD task to version 12.2 configure: Don't use the __atomic_*_16 functions for testing 128-bit support gitlab-ci.yml: Merge the trace-backend testing into other jobs tests/tcg: add HeapInfo checking to semihosting test linux-user/riscv: initialise the TaskState heap/stack info semihosting/arm-compat-semi: don't use SET_ARG to report SYS_HEAPINFO semihosting/arm-compat-semi: unify GET/SET_ARG helpers semihosting: move semihosting tests to multiarch tools/virtiofsd: include --socket-group in help docs/devel: expand style section of memory management ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
f0b6a6a1a9
|
@ -3,7 +3,7 @@ env:
|
||||||
|
|
||||||
freebsd_12_task:
|
freebsd_12_task:
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
image_family: freebsd-12-1
|
image_family: freebsd-12-2
|
||||||
cpu: 8
|
cpu: 8
|
||||||
memory: 8G
|
memory: 8G
|
||||||
install_script:
|
install_script:
|
||||||
|
@ -13,7 +13,10 @@ freebsd_12_task:
|
||||||
script:
|
script:
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd 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)
|
||||||
- gmake -j$(sysctl -n hw.ncpu) check V=1
|
- gmake -j$(sysctl -n hw.ncpu) check V=1
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
|
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
|
||||||
../configure --enable-werror $QEMU_CONFIGURE_OPTS --disable-user
|
../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
|
||||||
--target-list-exclude="arm-softmmu cris-softmmu i386-softmmu
|
--disable-user --target-list-exclude="arm-softmmu cris-softmmu
|
||||||
microblaze-softmmu mips-softmmu mipsel-softmmu mips64-softmmu
|
i386-softmmu microblaze-softmmu mips-softmmu mipsel-softmmu
|
||||||
ppc-softmmu sh4-softmmu xtensa-softmmu"
|
mips64-softmmu ppc-softmmu sh4-softmmu xtensa-softmmu"
|
||||||
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
|
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
|
||||||
|
|
||||||
# Job to cross-build specific accelerators.
|
# Job to cross-build specific accelerators.
|
||||||
|
@ -25,8 +25,8 @@
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
|
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
|
||||||
../configure --enable-werror $QEMU_CONFIGURE_OPTS --disable-tools
|
../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
|
||||||
--enable-${ACCEL:-kvm} $ACCEL_CONFIGURE_OPTS
|
--disable-tools --enable-${ACCEL:-kvm} $ACCEL_CONFIGURE_OPTS
|
||||||
- make -j$(expr $(nproc) + 1) all check-build
|
- make -j$(expr $(nproc) + 1) all check-build
|
||||||
|
|
||||||
.cross_user_build_job:
|
.cross_user_build_job:
|
||||||
|
@ -36,7 +36,8 @@
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
|
- 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
|
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
|
||||||
|
|
||||||
cross-armel-system:
|
cross-armel-system:
|
||||||
|
|
|
@ -23,9 +23,9 @@ include:
|
||||||
- cd build
|
- cd build
|
||||||
- if test -n "$TARGETS";
|
- if test -n "$TARGETS";
|
||||||
then
|
then
|
||||||
../configure --enable-werror $CONFIGURE_ARGS --target-list="$TARGETS" ;
|
../configure --enable-werror --disable-docs $CONFIGURE_ARGS --target-list="$TARGETS" ;
|
||||||
else
|
else
|
||||||
../configure --enable-werror $CONFIGURE_ARGS ;
|
../configure --enable-werror --disable-docs $CONFIGURE_ARGS ;
|
||||||
fi || { cat config.log meson-logs/meson-log.txt && exit 1; }
|
fi || { cat config.log meson-logs/meson-log.txt && exit 1; }
|
||||||
- if test -n "$LD_JOBS";
|
- if test -n "$LD_JOBS";
|
||||||
then
|
then
|
||||||
|
@ -87,7 +87,7 @@ build-system-alpine:
|
||||||
TARGETS: aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu
|
TARGETS: aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu
|
||||||
moxie-softmmu microblazeel-softmmu mips64el-softmmu
|
moxie-softmmu microblazeel-softmmu mips64el-softmmu
|
||||||
MAKE_CHECK_ARGS: check-build
|
MAKE_CHECK_ARGS: check-build
|
||||||
CONFIGURE_ARGS: --enable-docs
|
CONFIGURE_ARGS: --enable-docs --enable-trace-backends=log,simple,syslog
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 2 days
|
expire_in: 2 days
|
||||||
paths:
|
paths:
|
||||||
|
@ -119,7 +119,7 @@ build-system-ubuntu:
|
||||||
job: amd64-ubuntu2004-container
|
job: amd64-ubuntu2004-container
|
||||||
variables:
|
variables:
|
||||||
IMAGE: ubuntu2004
|
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
|
TARGETS: aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu
|
||||||
moxie-softmmu microblazeel-softmmu mips64el-softmmu
|
moxie-softmmu microblazeel-softmmu mips64el-softmmu
|
||||||
MAKE_CHECK_ARGS: check-build
|
MAKE_CHECK_ARGS: check-build
|
||||||
|
@ -502,6 +502,7 @@ build-cfi-aarch64:
|
||||||
--enable-safe-stack --enable-slirp=git
|
--enable-safe-stack --enable-slirp=git
|
||||||
TARGETS: aarch64-softmmu
|
TARGETS: aarch64-softmmu
|
||||||
MAKE_CHECK_ARGS: check-build
|
MAKE_CHECK_ARGS: check-build
|
||||||
|
timeout: 70m
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 2 days
|
expire_in: 2 days
|
||||||
paths:
|
paths:
|
||||||
|
@ -538,6 +539,7 @@ build-cfi-ppc64-s390x:
|
||||||
--enable-safe-stack --enable-slirp=git
|
--enable-safe-stack --enable-slirp=git
|
||||||
TARGETS: ppc64-softmmu s390x-softmmu
|
TARGETS: ppc64-softmmu s390x-softmmu
|
||||||
MAKE_CHECK_ARGS: check-build
|
MAKE_CHECK_ARGS: check-build
|
||||||
|
timeout: 70m
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 2 days
|
expire_in: 2 days
|
||||||
paths:
|
paths:
|
||||||
|
@ -574,6 +576,7 @@ build-cfi-x86_64:
|
||||||
--enable-safe-stack --enable-slirp=git
|
--enable-safe-stack --enable-slirp=git
|
||||||
TARGETS: x86_64-softmmu
|
TARGETS: x86_64-softmmu
|
||||||
MAKE_CHECK_ARGS: check-build
|
MAKE_CHECK_ARGS: check-build
|
||||||
|
timeout: 70m
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 2 days
|
expire_in: 2 days
|
||||||
paths:
|
paths:
|
||||||
|
@ -604,8 +607,8 @@ tsan-build:
|
||||||
job: amd64-ubuntu2004-container
|
job: amd64-ubuntu2004-container
|
||||||
variables:
|
variables:
|
||||||
IMAGE: ubuntu2004
|
IMAGE: ubuntu2004
|
||||||
CONFIGURE_ARGS: --enable-tsan --cc=clang-10 --cxx=clang++-10 --disable-docs
|
CONFIGURE_ARGS: --enable-tsan --cc=clang-10 --cxx=clang++-10
|
||||||
--enable-fdt=system --enable-slirp=system
|
--enable-trace-backends=ust --enable-fdt=system --enable-slirp=system
|
||||||
TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
|
TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
|
||||||
MAKE_CHECK_ARGS: bench V=1
|
MAKE_CHECK_ARGS: bench V=1
|
||||||
|
|
||||||
|
@ -616,7 +619,7 @@ build-deprecated:
|
||||||
job: amd64-debian-user-cross-container
|
job: amd64-debian-user-cross-container
|
||||||
variables:
|
variables:
|
||||||
IMAGE: debian-all-test-cross
|
IMAGE: debian-all-test-cross
|
||||||
CONFIGURE_ARGS: --disable-docs --disable-tools
|
CONFIGURE_ARGS: --disable-tools
|
||||||
MAKE_CHECK_ARGS: build-tcg
|
MAKE_CHECK_ARGS: build-tcg
|
||||||
TARGETS: ppc64abi32-linux-user lm32-softmmu unicore32-softmmu
|
TARGETS: ppc64abi32-linux-user lm32-softmmu unicore32-softmmu
|
||||||
artifacts:
|
artifacts:
|
||||||
|
@ -702,6 +705,7 @@ build-coroutine-sigaltstack:
|
||||||
variables:
|
variables:
|
||||||
IMAGE: ubuntu2004
|
IMAGE: ubuntu2004
|
||||||
CONFIGURE_ARGS: --with-coroutine=sigaltstack --disable-tcg
|
CONFIGURE_ARGS: --with-coroutine=sigaltstack --disable-tcg
|
||||||
|
--enable-trace-backends=ftrace
|
||||||
MAKE_CHECK_ARGS: check-unit
|
MAKE_CHECK_ARGS: check-unit
|
||||||
|
|
||||||
# Most jobs test latest gcrypt or nettle builds
|
# Most jobs test latest gcrypt or nettle builds
|
||||||
|
@ -739,31 +743,6 @@ crypto-only-gnutls:
|
||||||
MAKE_CHECK_ARGS: check
|
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
|
# Check our reduced build configurations
|
||||||
build-without-default-devices:
|
build-without-default-devices:
|
||||||
<<: *native_build_job_definition
|
<<: *native_build_job_definition
|
||||||
|
|
|
@ -3286,6 +3286,7 @@ M: Alex Bennée <alex.bennee@linaro.org>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: semihosting/
|
F: semihosting/
|
||||||
F: include/semihosting/
|
F: include/semihosting/
|
||||||
|
F: tests/tcg/multiarch/arm-compat-semi/
|
||||||
|
|
||||||
Multi-process QEMU
|
Multi-process QEMU
|
||||||
M: Elena Ufimtseva <elena.ufimtseva@oracle.com>
|
M: Elena Ufimtseva <elena.ufimtseva@oracle.com>
|
||||||
|
|
|
@ -962,11 +962,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type,
|
||||||
QemuOpts *devopts;
|
QemuOpts *devopts;
|
||||||
devopts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
|
devopts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
if (arch_type == QEMU_ARCH_S390X) {
|
qemu_opt_set(devopts, "driver", "virtio-blk", &error_abort);
|
||||||
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, "drive", qdict_get_str(bs_opts, "id"),
|
qemu_opt_set(devopts, "drive", qdict_get_str(bs_opts, "id"),
|
||||||
&error_abort);
|
&error_abort);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4779,9 +4779,9 @@ if test "$int128" = "yes"; then
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
unsigned __int128 x = 0, y = 0;
|
unsigned __int128 x = 0, y = 0;
|
||||||
y = __atomic_load_16(&x, 0);
|
y = __atomic_load(&x, 0);
|
||||||
__atomic_store_16(&x, y, 0);
|
__atomic_store(&x, y, 0);
|
||||||
__atomic_compare_exchange_16(&x, &y, x, 0, 0, 0);
|
__atomic_compare_exchange(&x, &y, x, 0, 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
|
@ -385,17 +385,37 @@ avoided.
|
||||||
Low level memory management
|
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,
|
APIs is not allowed in the QEMU codebase. Instead of these routines,
|
||||||
use the GLib memory allocation routines g_malloc/g_malloc0/g_new/
|
use the GLib memory allocation routines
|
||||||
g_new0/g_realloc/g_free or QEMU's qemu_memalign/qemu_blockalign/qemu_vfree
|
``g_malloc/g_malloc0/g_new/g_new0/g_realloc/g_free``
|
||||||
APIs.
|
or QEMU's ``qemu_memalign/qemu_blockalign/qemu_vfree`` APIs.
|
||||||
|
|
||||||
Please note that g_malloc will exit on allocation failure, so there
|
Please note that ``g_malloc`` will exit on allocation failure, so
|
||||||
is no need to test for failure (as you would have to with malloc).
|
there is no need to test for failure (as you would have to with
|
||||||
Calling g_malloc with a zero size is valid and will return NULL.
|
``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).
|
||||||
|
|
||||||
Prefer g_new(T, n) instead of g_malloc(sizeof(T) ``*`` n) for the following
|
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:
|
reasons:
|
||||||
|
|
||||||
* It catches multiplication overflowing size_t;
|
* It catches multiplication overflowing size_t;
|
||||||
|
@ -409,8 +429,8 @@ Declarations like
|
||||||
|
|
||||||
are acceptable, though.
|
are acceptable, though.
|
||||||
|
|
||||||
Memory allocated by qemu_memalign or qemu_blockalign must be freed with
|
Memory allocated by ``qemu_memalign`` or ``qemu_blockalign`` must be freed with
|
||||||
qemu_vfree, since breaking this will cause problems on Win32.
|
``qemu_vfree``, since breaking this will cause problems on Win32.
|
||||||
|
|
||||||
String manipulation
|
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
|
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.
|
documented in the GNU Compiler Collection manual starting at version 4.0.
|
||||||
|
|
||||||
|
.. _autofree-ref:
|
||||||
|
|
||||||
Automatic memory deallocation
|
Automatic memory deallocation
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
|
|
|
@ -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
|
information that is needed is extracted during the callback and saved
|
||||||
by the plugin.
|
by the plugin.
|
||||||
|
|
||||||
|
API
|
||||||
|
===
|
||||||
|
|
||||||
|
.. kernel-doc:: include/qemu/qemu-plugin.h
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
|
|
@ -35,4 +35,13 @@ extern const uint32_t arch_type;
|
||||||
int kvm_available(void);
|
int kvm_available(void);
|
||||||
int xen_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
|
#endif
|
||||||
|
|
|
@ -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");
|
error_report("Incompatible ELF: RVE cpu requires RVE ABI binary");
|
||||||
exit(EXIT_FAILURE);
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1745,6 +1745,9 @@ sub dump_function($$) {
|
||||||
)+
|
)+
|
||||||
\)\)\s+//x;
|
\)\)\s+//x;
|
||||||
|
|
||||||
|
# Strip QEMU specific compiler annotations
|
||||||
|
$prototype =~ s/QEMU_[A-Z_]+ +//;
|
||||||
|
|
||||||
# Yes, this truly is vile. We are looking for:
|
# Yes, this truly is vile. We are looking for:
|
||||||
# 1. Return type (may be nothing if we're looking at a macro)
|
# 1. Return type (may be nothing if we're looking at a macro)
|
||||||
# 2. Function name
|
# 2. Function name
|
||||||
|
|
|
@ -767,12 +767,25 @@ 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 { \
|
#define GET_ARG(n) do { \
|
||||||
if (is_a64(env)) { \
|
if (is_64bit_semihosting(env)) { \
|
||||||
if (get_user_u64(arg ## n, args + (n) * 8)) { \
|
if (get_user_u64(arg ## n, args + (n) * 8)) { \
|
||||||
errno = EFAULT; \
|
errno = EFAULT; \
|
||||||
return set_swi_errno(cs, -1); \
|
return set_swi_errno(cs, -1); \
|
||||||
|
@ -786,41 +799,10 @@ static const GuestFDFunctions guestfd_fns[] = {
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SET_ARG(n, val) \
|
#define SET_ARG(n, val) \
|
||||||
(is_a64(env) ? \
|
(is_64bit_semihosting(env) ? \
|
||||||
put_user_u64(val, args + (n) * 8) : \
|
put_user_u64(val, args + (n) * 8) : \
|
||||||
put_user_u32(val, args + (n) * 4))
|
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.
|
* Do a semihosting call.
|
||||||
|
@ -1232,7 +1214,11 @@ target_ulong do_common_semihosting(CPUState *cs)
|
||||||
for (i = 0; i < ARRAY_SIZE(retvals); i++) {
|
for (i = 0; i < ARRAY_SIZE(retvals); i++) {
|
||||||
bool fail;
|
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) {
|
if (fail) {
|
||||||
/* Couldn't write back to argument block */
|
/* Couldn't write back to argument block */
|
||||||
|
|
|
@ -60,34 +60,43 @@ static const QDevAlias qdev_alias_table[] = {
|
||||||
{ "ES1370", "es1370" }, /* -soundhw name */
|
{ "ES1370", "es1370" }, /* -soundhw name */
|
||||||
{ "ich9-ahci", "ahci" },
|
{ "ich9-ahci", "ahci" },
|
||||||
{ "lsi53c895a", "lsi" },
|
{ "lsi53c895a", "lsi" },
|
||||||
{ "virtio-9p-ccw", "virtio-9p", QEMU_ARCH_S390X },
|
{ "virtio-9p-device", "virtio-9p", QEMU_ARCH_VIRTIO_MMIO },
|
||||||
{ "virtio-9p-pci", "virtio-9p", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-9p-ccw", "virtio-9p", QEMU_ARCH_VIRTIO_CCW },
|
||||||
{ "virtio-balloon-ccw", "virtio-balloon", QEMU_ARCH_S390X },
|
{ "virtio-9p-pci", "virtio-9p", QEMU_ARCH_VIRTIO_PCI },
|
||||||
{ "virtio-balloon-pci", "virtio-balloon",
|
{ "virtio-balloon-device", "virtio-balloon", QEMU_ARCH_VIRTIO_MMIO },
|
||||||
QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-balloon-ccw", "virtio-balloon", QEMU_ARCH_VIRTIO_CCW },
|
||||||
{ "virtio-blk-ccw", "virtio-blk", QEMU_ARCH_S390X },
|
{ "virtio-balloon-pci", "virtio-balloon", QEMU_ARCH_VIRTIO_PCI },
|
||||||
{ "virtio-blk-pci", "virtio-blk", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-blk-device", "virtio-blk", QEMU_ARCH_VIRTIO_MMIO },
|
||||||
{ "virtio-gpu-ccw", "virtio-gpu", QEMU_ARCH_S390X },
|
{ "virtio-blk-ccw", "virtio-blk", QEMU_ARCH_VIRTIO_CCW },
|
||||||
{ "virtio-gpu-pci", "virtio-gpu", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-blk-pci", "virtio-blk", QEMU_ARCH_VIRTIO_PCI },
|
||||||
{ "virtio-input-host-ccw", "virtio-input-host", QEMU_ARCH_S390X },
|
{ "virtio-gpu-device", "virtio-gpu", QEMU_ARCH_VIRTIO_MMIO },
|
||||||
{ "virtio-input-host-pci", "virtio-input-host",
|
{ "virtio-gpu-ccw", "virtio-gpu", QEMU_ARCH_VIRTIO_CCW },
|
||||||
QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-gpu-pci", "virtio-gpu", QEMU_ARCH_VIRTIO_PCI },
|
||||||
{ "virtio-iommu-pci", "virtio-iommu", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-input-host-device", "virtio-input-host", QEMU_ARCH_VIRTIO_MMIO },
|
||||||
{ "virtio-keyboard-ccw", "virtio-keyboard", QEMU_ARCH_S390X },
|
{ "virtio-input-host-ccw", "virtio-input-host", QEMU_ARCH_VIRTIO_CCW },
|
||||||
{ "virtio-keyboard-pci", "virtio-keyboard",
|
{ "virtio-input-host-pci", "virtio-input-host", QEMU_ARCH_VIRTIO_PCI },
|
||||||
QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-iommu-pci", "virtio-iommu", QEMU_ARCH_VIRTIO_PCI },
|
||||||
{ "virtio-mouse-ccw", "virtio-mouse", QEMU_ARCH_S390X },
|
{ "virtio-keyboard-device", "virtio-keyboard", QEMU_ARCH_VIRTIO_MMIO },
|
||||||
{ "virtio-mouse-pci", "virtio-mouse", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-keyboard-ccw", "virtio-keyboard", QEMU_ARCH_VIRTIO_CCW },
|
||||||
{ "virtio-net-ccw", "virtio-net", QEMU_ARCH_S390X },
|
{ "virtio-keyboard-pci", "virtio-keyboard", QEMU_ARCH_VIRTIO_PCI },
|
||||||
{ "virtio-net-pci", "virtio-net", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-mouse-device", "virtio-mouse", QEMU_ARCH_VIRTIO_MMIO },
|
||||||
{ "virtio-rng-ccw", "virtio-rng", QEMU_ARCH_S390X },
|
{ "virtio-mouse-ccw", "virtio-mouse", QEMU_ARCH_VIRTIO_CCW },
|
||||||
{ "virtio-rng-pci", "virtio-rng", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-mouse-pci", "virtio-mouse", QEMU_ARCH_VIRTIO_PCI },
|
||||||
{ "virtio-scsi-ccw", "virtio-scsi", QEMU_ARCH_S390X },
|
{ "virtio-net-device", "virtio-net", QEMU_ARCH_VIRTIO_MMIO },
|
||||||
{ "virtio-scsi-pci", "virtio-scsi", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-net-ccw", "virtio-net", QEMU_ARCH_VIRTIO_CCW },
|
||||||
{ "virtio-serial-ccw", "virtio-serial", QEMU_ARCH_S390X },
|
{ "virtio-net-pci", "virtio-net", QEMU_ARCH_VIRTIO_PCI },
|
||||||
{ "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "virtio-rng-device", "virtio-rng", QEMU_ARCH_VIRTIO_MMIO },
|
||||||
{ "virtio-tablet-ccw", "virtio-tablet", QEMU_ARCH_S390X },
|
{ "virtio-rng-ccw", "virtio-rng", QEMU_ARCH_VIRTIO_CCW },
|
||||||
{ "virtio-tablet-pci", "virtio-tablet", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
|
{ "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 },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ class TestSingleDrive(ImageCommitTestCase):
|
||||||
qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', backing_img)
|
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)
|
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 = 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.add_device("scsi-hd,id=scsi0,drive=drive0")
|
||||||
self.vm.launch()
|
self.vm.launch()
|
||||||
self.has_quit = False
|
self.has_quit = False
|
||||||
|
|
|
@ -119,17 +119,7 @@ echo
|
||||||
echo === Device without drive ===
|
echo === Device without drive ===
|
||||||
echo
|
echo
|
||||||
|
|
||||||
case "$QEMU_DEFAULT_MACHINE" in
|
run_qemu -device virtio-scsi -device scsi-hd
|
||||||
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/"
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo === Overriding backing file ===
|
echo === Overriding backing file ===
|
||||||
|
|
|
@ -72,7 +72,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,node-name=foo#12: Invalid node name
|
||||||
|
|
||||||
=== Device without drive ===
|
=== 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 X.Y.Z monitor - type 'help' for more information
|
||||||
(qemu) QEMU_PROG: -device scsi-hd: drive property not set
|
(qemu) QEMU_PROG: -device scsi-hd: drive property not set
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,node-name=foo#12: Invalid node-name: 'fo
|
||||||
|
|
||||||
=== Device without drive ===
|
=== 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 X.Y.Z monitor - type 'help' for more information
|
||||||
(qemu) QEMU_PROG: -device scsi-hd: drive property not set
|
(qemu) QEMU_PROG: -device scsi-hd: drive property not set
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,9 @@ IMG_SIZE=128K
|
||||||
case "$QEMU_DEFAULT_MACHINE" in
|
case "$QEMU_DEFAULT_MACHINE" in
|
||||||
s390-ccw-virtio)
|
s390-ccw-virtio)
|
||||||
platform_parm="-no-shutdown"
|
platform_parm="-no-shutdown"
|
||||||
hba=virtio-scsi-ccw
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
platform_parm=""
|
platform_parm=""
|
||||||
hba=virtio-scsi-pci
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -61,7 +59,7 @@ _qemu()
|
||||||
{
|
{
|
||||||
$QEMU $platform_parm -nographic -monitor stdio -serial none \
|
$QEMU $platform_parm -nographic -monitor stdio -serial none \
|
||||||
-drive if=none,id=drive0,file="$TEST_IMG",format="$IMGFMT" \
|
-drive if=none,id=drive0,file="$TEST_IMG",format="$IMGFMT" \
|
||||||
-device $hba,id=hba0 \
|
-device virtio-scsi,id=hba0 \
|
||||||
-device scsi-hd,drive=drive0 \
|
-device scsi-hd,drive=drive0 \
|
||||||
"$@" |\
|
"$@" |\
|
||||||
_filter_qemu | _filter_hmp
|
_filter_qemu | _filter_hmp
|
||||||
|
|
|
@ -371,8 +371,7 @@ class ThrottleTestGroupNames(iotests.QMPTestCase):
|
||||||
class ThrottleTestRemovableMedia(iotests.QMPTestCase):
|
class ThrottleTestRemovableMedia(iotests.QMPTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.vm = iotests.VM()
|
self.vm = iotests.VM()
|
||||||
self.vm.add_device("{},id=virtio-scsi".format(
|
self.vm.add_device("{},id=virtio-scsi".format('virtio-scsi'))
|
||||||
iotests.get_virtio_scsi_device()))
|
|
||||||
self.vm.launch()
|
self.vm.launch()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
|
@ -44,7 +44,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||||
_supported_fmt qcow2
|
_supported_fmt qcow2
|
||||||
_supported_proto file fuse
|
_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
|
IMG_SIZE=64K
|
||||||
|
|
||||||
|
|
|
@ -26,18 +26,13 @@ import time
|
||||||
|
|
||||||
base_img = os.path.join(iotests.test_dir, 'base.img')
|
base_img = os.path.join(iotests.test_dir, 'base.img')
|
||||||
new_img = os.path.join(iotests.test_dir, 'new.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):
|
class TestBlockdevDel(iotests.QMPTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
iotests.qemu_img('create', '-f', iotests.imgfmt, base_img, '1M')
|
iotests.qemu_img('create', '-f', iotests.imgfmt, base_img, '1M')
|
||||||
self.vm = iotests.VM()
|
self.vm = iotests.VM()
|
||||||
self.vm.add_device("{},id=virtio-scsi".format(
|
self.vm.add_device("{},id=virtio-scsi".format('virtio-scsi'))
|
||||||
iotests.get_virtio_scsi_device()))
|
|
||||||
self.vm.launch()
|
self.vm.launch()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
@ -93,7 +88,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
|
||||||
self.checkBlockDriverState(node, expect_error)
|
self.checkBlockDriverState(node, expect_error)
|
||||||
|
|
||||||
# Add a device model
|
# 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,
|
result = self.vm.qmp('device_add', id = device,
|
||||||
driver = driver, drive = backend)
|
driver = driver, drive = backend)
|
||||||
self.assert_qmp(result, 'return', {})
|
self.assert_qmp(result, 'return', {})
|
||||||
|
|
|
@ -46,26 +46,17 @@ _supported_proto file
|
||||||
|
|
||||||
size=32M
|
size=32M
|
||||||
|
|
||||||
case "$QEMU_DEFAULT_MACHINE" in
|
|
||||||
s390-ccw-virtio)
|
|
||||||
virtioblk=virtio-blk-ccw
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
virtioblk=virtio-blk-pci
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
_make_test_img $size
|
_make_test_img $size
|
||||||
|
|
||||||
echo "Starting QEMU"
|
echo "Starting QEMU"
|
||||||
_launch_qemu -drive file=$TEST_IMG,if=none,id=drive0,file.locking=on \
|
_launch_qemu -drive file=$TEST_IMG,if=none,id=drive0,file.locking=on \
|
||||||
-device $virtioblk,drive=drive0
|
-device virtio-blk,drive=drive0
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Starting a second QEMU using the same image should fail"
|
echo "Starting a second QEMU using the same image should fail"
|
||||||
echo 'quit' | $QEMU -nographic -monitor stdio \
|
echo 'quit' | $QEMU -nographic -monitor stdio \
|
||||||
-drive file=$TEST_IMG,if=none,id=drive0,file.locking=on \
|
-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 |
|
_filter_qemu |
|
||||||
sed -e '/falling back to POSIX file/d' \
|
sed -e '/falling back to POSIX file/d' \
|
||||||
-e '/locks can be lost unexpectedly/d'
|
-e '/locks can be lost unexpectedly/d'
|
||||||
|
|
|
@ -26,14 +26,12 @@ from iotests import log
|
||||||
|
|
||||||
iotests.script_initialize()
|
iotests.script_initialize()
|
||||||
|
|
||||||
virtio_scsi_device = iotests.get_virtio_scsi_device()
|
|
||||||
|
|
||||||
vm = iotests.VM()
|
vm = iotests.VM()
|
||||||
vm.launch()
|
vm.launch()
|
||||||
|
|
||||||
log(vm.qmp('blockdev-add', node_name='hd0', driver='null-co', read_zeroes=True))
|
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('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('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,
|
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))
|
iops=1000, iops_rd=0, iops_wr=0, conv_keys=False))
|
||||||
|
|
|
@ -42,7 +42,7 @@ class TestCase(iotests.QMPTestCase):
|
||||||
iotests.log('==Unplug a SCSI disk and then plug it again==')
|
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('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('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-hd0', driver='scsi-hd', drive='hd0')
|
||||||
self.vm.qmp_log('device_del', id='scsi-hd0')
|
self.vm.qmp_log('device_del', id='scsi-hd0')
|
||||||
self.vm.event_wait('DEVICE_DELETED')
|
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==')
|
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('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('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-hd0', driver='scsi-hd', drive='hd0')
|
||||||
self.vm.qmp_log('device_add', id='scsi-hd1', 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="iothread0")
|
||||||
self.vm.qmp_log('object-add', qom_type='iothread', id="iothread1")
|
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='scsi0', driver='virtio-scsi', 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='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-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")
|
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('nbd-server-add', device='hd0')
|
||||||
|
|
||||||
self.vm.qmp_log('object-add', qom_type='iothread', id="iothread0")
|
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-hd0', driver='scsi-hd', drive='hd0')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -24,6 +24,8 @@ import os
|
||||||
import iotests
|
import iotests
|
||||||
from iotests import log
|
from iotests import log
|
||||||
|
|
||||||
|
iotests._verify_virtio_scsi_pci_or_ccw()
|
||||||
|
|
||||||
iotests.script_initialize(supported_fmts=['qcow2'])
|
iotests.script_initialize(supported_fmts=['qcow2'])
|
||||||
size = 64 * 1024 * 1024
|
size = 64 * 1024 * 1024
|
||||||
|
|
||||||
|
@ -61,8 +63,8 @@ with iotests.FilePath('img0') as img0_path, \
|
||||||
log('--- Preparing images & VM ---\n')
|
log('--- Preparing images & VM ---\n')
|
||||||
vm.add_object('iothread,id=iothread0')
|
vm.add_object('iothread,id=iothread0')
|
||||||
vm.add_object('iothread,id=iothread1')
|
vm.add_object('iothread,id=iothread1')
|
||||||
vm.add_device('virtio-scsi-pci,id=scsi0,iothread=iothread0')
|
vm.add_device('virtio-scsi,id=scsi0,iothread=iothread0')
|
||||||
vm.add_device('virtio-scsi-pci,id=scsi1,iothread=iothread1')
|
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, img0_path, str(size))
|
||||||
iotests.qemu_img_create('-f', iotests.imgfmt, img1_path, str(size))
|
iotests.qemu_img_create('-f', iotests.imgfmt, img1_path, str(size))
|
||||||
vm.add_drive(img0_path, interface='none')
|
vm.add_drive(img0_path, interface='none')
|
||||||
|
|
|
@ -292,7 +292,7 @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
|
||||||
log('--- Preparing image & VM ---\n')
|
log('--- Preparing image & VM ---\n')
|
||||||
drive0 = Drive(img_path, vm=vm)
|
drive0 = Drive(img_path, vm=vm)
|
||||||
drive0.img_create(iotests.imgfmt, SIZE)
|
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()
|
vm.launch()
|
||||||
|
|
||||||
file_config = {
|
file_config = {
|
||||||
|
@ -449,7 +449,7 @@ def test_backup_api():
|
||||||
log('--- Preparing image & VM ---\n')
|
log('--- Preparing image & VM ---\n')
|
||||||
drive0 = Drive(img_path, vm=vm)
|
drive0 = Drive(img_path, vm=vm)
|
||||||
drive0.img_create(iotests.imgfmt, SIZE)
|
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()
|
vm.launch()
|
||||||
|
|
||||||
file_config = {
|
file_config = {
|
||||||
|
|
|
@ -40,13 +40,11 @@ with iotests.FilePath('image') as img, \
|
||||||
|
|
||||||
iotests.log('=== Launch VM ===')
|
iotests.log('=== Launch VM ===')
|
||||||
|
|
||||||
virtio_scsi_device = iotests.get_virtio_scsi_device()
|
|
||||||
|
|
||||||
vm.add_object('iothread,id=iothread0')
|
vm.add_object('iothread,id=iothread0')
|
||||||
vm.add_blockdev(f'file,filename={img},node-name=file')
|
vm.add_blockdev(f'file,filename={img},node-name=file')
|
||||||
vm.add_blockdev(f'{iotests.imgfmt},file=file,node-name=fmt')
|
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_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.launch()
|
||||||
|
|
||||||
vm.qmp_log('nbd-server-start',
|
vm.qmp_log('nbd-server-start',
|
||||||
|
|
|
@ -977,5 +977,18 @@ _require_devices()
|
||||||
done
|
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
|
# make sure this script returns success
|
||||||
true
|
true
|
||||||
|
|
|
@ -234,11 +234,6 @@ def qemu_io_silent_check(*args):
|
||||||
stderr=subprocess.STDOUT)
|
stderr=subprocess.STDOUT)
|
||||||
return exitcode == 0
|
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:
|
class QemuIoInteractive:
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
self.args = qemu_io_args_no_fmt + list(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:
|
if 'virtio-blk' not in out:
|
||||||
notrun('Missing virtio-blk in QEMU binary')
|
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():
|
def supports_quorum():
|
||||||
return 'quorum' in qemu_img_pipe('--help')
|
return 'quorum' in qemu_img_pipe('--help')
|
||||||
|
|
|
@ -208,6 +208,7 @@ class TestEnv(ContextManager['TestEnv']):
|
||||||
('arm', 'virt'),
|
('arm', 'virt'),
|
||||||
('aarch64', 'virt'),
|
('aarch64', 'virt'),
|
||||||
('avr', 'mega2560'),
|
('avr', 'mega2560'),
|
||||||
|
('m68k', 'virt'),
|
||||||
('rx', 'gdbsim-r5f562n8'),
|
('rx', 'gdbsim-r5f562n8'),
|
||||||
('tricore', 'tricore_testboard')
|
('tricore', 'tricore_testboard')
|
||||||
)
|
)
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
all:
|
all:
|
||||||
-include ../../../config-host.mak
|
-include ../../../config-host.mak
|
||||||
-include ../config-$(TARGET).mak
|
-include ../config-$(TARGET).mak
|
||||||
|
ifeq ($(CONFIG_USER_ONLY),y)
|
||||||
|
-include $(SRC_PATH)/default-configs/targets/$(TARGET).mak
|
||||||
|
endif
|
||||||
|
|
||||||
# for including , in command strings
|
# for including , in command strings
|
||||||
COMMA := ,
|
COMMA := ,
|
||||||
|
|
|
@ -41,24 +41,6 @@ AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4
|
||||||
mte-%: CFLAGS += -march=armv8.5-a+memtag
|
mte-%: CFLAGS += -march=armv8.5-a+memtag
|
||||||
endif
|
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),)
|
ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_SVE),)
|
||||||
# System Registers Tests
|
# System Registers Tests
|
||||||
AARCH64_TESTS += sysregs
|
AARCH64_TESTS += sysregs
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -29,37 +29,31 @@ run-fcvt: fcvt
|
||||||
$(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)")
|
$(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)")
|
||||||
$(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
|
$(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARM_COMPATIBLE_SEMIHOSTING),y)
|
||||||
|
|
||||||
# Semihosting smoke test for linux-user
|
# Semihosting smoke test for linux-user
|
||||||
ARM_TESTS += semihosting
|
|
||||||
semihosting: CFLAGS += -mthumb
|
semihosting: CFLAGS += -mthumb
|
||||||
run-semihosting: semihosting
|
|
||||||
$(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
|
|
||||||
|
|
||||||
ARM_TESTS += semihosting-arm
|
ARM_TESTS += semihosting-arm
|
||||||
semihosting-arm: CFLAGS += -marm
|
semihosting-arm: CFLAGS += -marm -I$(SRC_PATH)/tests/tcg/$(TARGET_NAME)
|
||||||
semihosting-arm: semihosting.c
|
semihosting-arm: semihosting.c
|
||||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
run-semihosting-arm: semihosting-arm
|
run-semihosting-arm: semihosting-arm
|
||||||
$(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
|
$(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
|
||||||
|
|
||||||
run-plugin-semihosting-with-%:
|
run-plugin-semihosting-arm-with-%:
|
||||||
$(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
|
$(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
|
||||||
-plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \
|
-plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \
|
||||||
$(call strip-plugin,$<) 2> $<.err, \
|
$(call strip-plugin,$<) 2> $<.err, \
|
||||||
"$< on $(TARGET_NAME) with $*")
|
"$< on $(TARGET_NAME) with $*")
|
||||||
|
|
||||||
ARM_TESTS += semiconsole semiconsole-arm
|
ARM_TESTS += semiconsole-arm
|
||||||
|
|
||||||
semiconsole: CFLAGS += -mthumb
|
semiconsole: CFLAGS += -mthumb
|
||||||
run-semiconsole: semiconsole
|
|
||||||
$(call skip-test, $<, "MANUAL ONLY")
|
|
||||||
|
|
||||||
run-plugin-semiconsole-with-%:
|
semiconsole-arm: CFLAGS += -marm -I$(SRC_PATH)/tests/tcg/$(TARGET_NAME)
|
||||||
$(call skip-test, $<, "MANUAL ONLY")
|
semiconsole-arm: semihosting.c
|
||||||
|
|
||||||
semiconsole-arm: CFLAGS += -marm
|
|
||||||
semiconsole-arm: semiconsole.c
|
|
||||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
run-semiconsole-arm: semiconsole-arm
|
run-semiconsole-arm: semiconsole-arm
|
||||||
|
@ -68,6 +62,8 @@ run-semiconsole-arm: semiconsole-arm
|
||||||
run-plugin-semiconsole-arm-with-%:
|
run-plugin-semiconsole-arm-with-%:
|
||||||
$(call skip-test, $<, "MANUAL ONLY")
|
$(call skip-test, $<, "MANUAL ONLY")
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
ARM_TESTS += commpage
|
ARM_TESTS += commpage
|
||||||
|
|
||||||
TESTS += $(ARM_TESTS)
|
TESTS += $(ARM_TESTS)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Semihosting Tests
|
* Semihosting Tests - ARM Helper
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019
|
* Copyright (c) 2019
|
||||||
* Written by Alex Bennée <alex.bennee@linaro.org>
|
* Written by Alex Bennée <alex.bennee@linaro.org>
|
||||||
|
@ -7,13 +7,8 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* 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)
|
uintptr_t __semi_call(uintptr_t type, uintptr_t arg0)
|
||||||
{
|
{
|
||||||
#if defined(__arm__)
|
|
||||||
register uintptr_t t asm("r0") = type;
|
register uintptr_t t asm("r0") = type;
|
||||||
register uintptr_t a0 asm("r1") = arg0;
|
register uintptr_t a0 asm("r1") = arg0;
|
||||||
#ifdef __thumb__
|
#ifdef __thumb__
|
||||||
|
@ -23,13 +18,5 @@ uintptr_t __semi_call(uintptr_t type, uintptr_t arg0)
|
||||||
#endif
|
#endif
|
||||||
asm(SVC : "=r" (t)
|
asm(SVC : "=r" (t)
|
||||||
: "r" (t), "r" (a0));
|
: "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;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -69,6 +69,37 @@ run-gdbstub-%:
|
||||||
endif
|
endif
|
||||||
EXTRA_RUNS += run-gdbstub-sha1 run-gdbstub-qxfer-auxv-read
|
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
|
# Update TESTS
|
||||||
TESTS += $(MULTIARCH_TESTS)
|
TESTS += $(MULTIARCH_TESTS)
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define SYS_READC 0x07
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "semicall.h"
|
#include "semicall.h"
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -378,6 +378,15 @@ static void test_qemu_strtoi_hex(void)
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0x123);
|
g_assert_cmpint(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
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)
|
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_cmpint(err, ==, 0);
|
||||||
g_assert_cmphex(res, ==, 0x123);
|
g_assert_cmphex(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
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)
|
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(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0x123);
|
g_assert_cmpint(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
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)
|
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_cmpint(err, ==, 0);
|
||||||
g_assert_cmphex(res, ==, 0x123);
|
g_assert_cmphex(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
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)
|
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(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0x123);
|
g_assert_cmpint(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
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)
|
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_cmpint(err, ==, 0);
|
||||||
g_assert_cmphex(res, ==, 0x123);
|
g_assert_cmphex(res, ==, 0x123);
|
||||||
g_assert(endptr == str + strlen(str));
|
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)
|
static void test_qemu_strtou64_max(void)
|
||||||
|
@ -1952,9 +2006,11 @@ static void test_qemu_strtosz_simple(void)
|
||||||
const char *str;
|
const char *str;
|
||||||
const char *endptr;
|
const char *endptr;
|
||||||
int err;
|
int err;
|
||||||
uint64_t res = 0xbaadf00d;
|
uint64_t res;
|
||||||
|
|
||||||
str = "0";
|
str = "0";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0);
|
g_assert_cmpint(res, ==, 0);
|
||||||
|
@ -1962,6 +2018,8 @@ static void test_qemu_strtosz_simple(void)
|
||||||
|
|
||||||
/* Leading 0 gives decimal results, not octal */
|
/* Leading 0 gives decimal results, not octal */
|
||||||
str = "08";
|
str = "08";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 8);
|
g_assert_cmpint(res, ==, 8);
|
||||||
|
@ -1969,46 +2027,61 @@ static void test_qemu_strtosz_simple(void)
|
||||||
|
|
||||||
/* Leading space is ignored */
|
/* Leading space is ignored */
|
||||||
str = " 12345";
|
str = " 12345";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 12345);
|
g_assert_cmpint(res, ==, 12345);
|
||||||
g_assert(endptr == str + 6);
|
g_assert(endptr == str + 6);
|
||||||
|
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, NULL, &res);
|
err = qemu_strtosz(str, NULL, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 12345);
|
g_assert_cmpint(res, ==, 12345);
|
||||||
|
|
||||||
str = "9007199254740991"; /* 2^53-1 */
|
str = "9007199254740991"; /* 2^53-1 */
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0x1fffffffffffff);
|
g_assert_cmpint(res, ==, 0x1fffffffffffff);
|
||||||
g_assert(endptr == str + 16);
|
g_assert(endptr == str + 16);
|
||||||
|
|
||||||
str = "9007199254740992"; /* 2^53 */
|
str = "9007199254740992"; /* 2^53 */
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0x20000000000000);
|
g_assert_cmpint(res, ==, 0x20000000000000);
|
||||||
g_assert(endptr == str + 16);
|
g_assert(endptr == str + 16);
|
||||||
|
|
||||||
str = "9007199254740993"; /* 2^53+1 */
|
str = "9007199254740993"; /* 2^53+1 */
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0x20000000000001);
|
g_assert_cmpint(res, ==, 0x20000000000001);
|
||||||
g_assert(endptr == str + 16);
|
g_assert(endptr == str + 16);
|
||||||
|
|
||||||
str = "18446744073709549568"; /* 0xfffffffffffff800 (53 msbs set) */
|
str = "18446744073709549568"; /* 0xfffffffffffff800 (53 msbs set) */
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0xfffffffffffff800);
|
g_assert_cmpint(res, ==, 0xfffffffffffff800);
|
||||||
g_assert(endptr == str + 20);
|
g_assert(endptr == str + 20);
|
||||||
|
|
||||||
str = "18446744073709550591"; /* 0xfffffffffffffbff */
|
str = "18446744073709550591"; /* 0xfffffffffffffbff */
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0xfffffffffffffbff);
|
g_assert_cmpint(res, ==, 0xfffffffffffffbff);
|
||||||
g_assert(endptr == str + 20);
|
g_assert(endptr == str + 20);
|
||||||
|
|
||||||
str = "18446744073709551615"; /* 0xffffffffffffffff */
|
str = "18446744073709551615"; /* 0xffffffffffffffff */
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0xffffffffffffffff);
|
g_assert_cmpint(res, ==, 0xffffffffffffffff);
|
||||||
|
@ -2020,21 +2093,27 @@ static void test_qemu_strtosz_hex(void)
|
||||||
const char *str;
|
const char *str;
|
||||||
const char *endptr;
|
const char *endptr;
|
||||||
int err;
|
int err;
|
||||||
uint64_t res = 0xbaadf00d;
|
uint64_t res;
|
||||||
|
|
||||||
str = "0x0";
|
str = "0x0";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0);
|
g_assert_cmpint(res, ==, 0);
|
||||||
g_assert(endptr == str + 3);
|
g_assert(endptr == str + 3);
|
||||||
|
|
||||||
str = "0xab";
|
str = "0xab";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 171);
|
g_assert_cmpint(res, ==, 171);
|
||||||
g_assert(endptr == str + 4);
|
g_assert(endptr == str + 4);
|
||||||
|
|
||||||
str = "0xae";
|
str = "0xae";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 174);
|
g_assert_cmpint(res, ==, 174);
|
||||||
|
@ -2053,44 +2132,60 @@ static void test_qemu_strtosz_units(void)
|
||||||
const char *e = "1E";
|
const char *e = "1E";
|
||||||
int err;
|
int err;
|
||||||
const char *endptr;
|
const char *endptr;
|
||||||
uint64_t res = 0xbaadf00d;
|
uint64_t res;
|
||||||
|
|
||||||
/* default is M */
|
/* default is M */
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz_MiB(none, &endptr, &res);
|
err = qemu_strtosz_MiB(none, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, MiB);
|
g_assert_cmpint(res, ==, MiB);
|
||||||
g_assert(endptr == none + 1);
|
g_assert(endptr == none + 1);
|
||||||
|
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(b, &endptr, &res);
|
err = qemu_strtosz(b, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 1);
|
g_assert_cmpint(res, ==, 1);
|
||||||
g_assert(endptr == b + 2);
|
g_assert(endptr == b + 2);
|
||||||
|
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(k, &endptr, &res);
|
err = qemu_strtosz(k, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, KiB);
|
g_assert_cmpint(res, ==, KiB);
|
||||||
g_assert(endptr == k + 2);
|
g_assert(endptr == k + 2);
|
||||||
|
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(m, &endptr, &res);
|
err = qemu_strtosz(m, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, MiB);
|
g_assert_cmpint(res, ==, MiB);
|
||||||
g_assert(endptr == m + 2);
|
g_assert(endptr == m + 2);
|
||||||
|
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(g, &endptr, &res);
|
err = qemu_strtosz(g, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, GiB);
|
g_assert_cmpint(res, ==, GiB);
|
||||||
g_assert(endptr == g + 2);
|
g_assert(endptr == g + 2);
|
||||||
|
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(t, &endptr, &res);
|
err = qemu_strtosz(t, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, TiB);
|
g_assert_cmpint(res, ==, TiB);
|
||||||
g_assert(endptr == t + 2);
|
g_assert(endptr == t + 2);
|
||||||
|
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(p, &endptr, &res);
|
err = qemu_strtosz(p, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, PiB);
|
g_assert_cmpint(res, ==, PiB);
|
||||||
g_assert(endptr == p + 2);
|
g_assert(endptr == p + 2);
|
||||||
|
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(e, &endptr, &res);
|
err = qemu_strtosz(e, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, EiB);
|
g_assert_cmpint(res, ==, EiB);
|
||||||
|
@ -2102,9 +2197,11 @@ static void test_qemu_strtosz_float(void)
|
||||||
const char *str;
|
const char *str;
|
||||||
int err;
|
int err;
|
||||||
const char *endptr;
|
const char *endptr;
|
||||||
uint64_t res = 0xbaadf00d;
|
uint64_t res;
|
||||||
|
|
||||||
str = "0.5E";
|
str = "0.5E";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, EiB / 2);
|
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 */
|
/* For convenience, a fraction of 0 is tolerated even on bytes */
|
||||||
str = "1.0B";
|
str = "1.0B";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 1);
|
g_assert_cmpint(res, ==, 1);
|
||||||
|
@ -2119,6 +2218,8 @@ static void test_qemu_strtosz_float(void)
|
||||||
|
|
||||||
/* An empty fraction is tolerated */
|
/* An empty fraction is tolerated */
|
||||||
str = "1.k";
|
str = "1.k";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 1024);
|
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 */
|
/* For convenience, we permit values that are not byte-exact */
|
||||||
str = "12.345M";
|
str = "12.345M";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, (uint64_t) (12.345 * MiB + 0.5));
|
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;
|
uint64_t res = 0xbaadf00d;
|
||||||
|
|
||||||
str = "";
|
str = "";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
str = " \t ";
|
str = " \t ";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
str = "crap";
|
str = "crap";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
str = "inf";
|
str = "inf";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
str = "NaN";
|
str = "NaN";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
/* Fractional values require scale larger than bytes */
|
/* Fractional values require scale larger than bytes */
|
||||||
str = "1.1B";
|
str = "1.1B";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
str = "1.1";
|
str = "1.1";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
/* No floating point exponents */
|
/* No floating point exponents */
|
||||||
str = "1.5e1k";
|
str = "1.5e1k";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
str = "1.5E+0k";
|
str = "1.5E+0k";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
/* No hex fractions */
|
/* No hex fractions */
|
||||||
str = "0x1.8k";
|
str = "0x1.8k";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
/* No negative values */
|
/* No negative values */
|
||||||
str = "-0";
|
str = "-0";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
|
|
||||||
str = "-1";
|
str = "-1";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str);
|
g_assert(endptr == str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2209,48 +2336,72 @@ static void test_qemu_strtosz_trailing(void)
|
||||||
const char *str;
|
const char *str;
|
||||||
const char *endptr;
|
const char *endptr;
|
||||||
int err;
|
int err;
|
||||||
uint64_t res = 0xbaadf00d;
|
uint64_t res;
|
||||||
|
|
||||||
str = "123xxx";
|
str = "123xxx";
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz_MiB(str, &endptr, &res);
|
err = qemu_strtosz_MiB(str, &endptr, &res);
|
||||||
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 123 * MiB);
|
g_assert_cmpint(res, ==, 123 * MiB);
|
||||||
g_assert(endptr == str + 3);
|
g_assert(endptr == str + 3);
|
||||||
|
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, NULL, &res);
|
err = qemu_strtosz(str, NULL, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
|
|
||||||
str = "1kiB";
|
str = "1kiB";
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 1024);
|
g_assert_cmpint(res, ==, 1024);
|
||||||
g_assert(endptr == str + 2);
|
g_assert(endptr == str + 2);
|
||||||
|
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, NULL, &res);
|
err = qemu_strtosz(str, NULL, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
|
|
||||||
str = "0x";
|
str = "0x";
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 0);
|
g_assert_cmpint(res, ==, 0);
|
||||||
g_assert(endptr == str + 1);
|
g_assert(endptr == str + 1);
|
||||||
|
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, NULL, &res);
|
err = qemu_strtosz(str, NULL, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
|
|
||||||
str = "0.NaN";
|
str = "0.NaN";
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
|
g_assert_cmpint(res, ==, 0);
|
||||||
g_assert(endptr == str + 2);
|
g_assert(endptr == str + 2);
|
||||||
|
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, NULL, &res);
|
err = qemu_strtosz(str, NULL, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
|
|
||||||
str = "123-45";
|
str = "123-45";
|
||||||
|
endptr = NULL;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 123);
|
g_assert_cmpint(res, ==, 123);
|
||||||
g_assert(endptr == str + 3);
|
g_assert(endptr == str + 3);
|
||||||
|
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz(str, NULL, &res);
|
err = qemu_strtosz(str, NULL, &res);
|
||||||
g_assert_cmpint(err, ==, -EINVAL);
|
g_assert_cmpint(err, ==, -EINVAL);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_qemu_strtosz_erange(void)
|
static void test_qemu_strtosz_erange(void)
|
||||||
|
@ -2261,13 +2412,17 @@ static void test_qemu_strtosz_erange(void)
|
||||||
uint64_t res = 0xbaadf00d;
|
uint64_t res = 0xbaadf00d;
|
||||||
|
|
||||||
str = "18446744073709551616"; /* 2^64; see strtosz_simple for 2^64-1 */
|
str = "18446744073709551616"; /* 2^64; see strtosz_simple for 2^64-1 */
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -ERANGE);
|
g_assert_cmpint(err, ==, -ERANGE);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str + 20);
|
g_assert(endptr == str + 20);
|
||||||
|
|
||||||
str = "20E";
|
str = "20E";
|
||||||
|
endptr = NULL;
|
||||||
err = qemu_strtosz(str, &endptr, &res);
|
err = qemu_strtosz(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, -ERANGE);
|
g_assert_cmpint(err, ==, -ERANGE);
|
||||||
|
g_assert_cmpint(res, ==, 0xbaadf00d);
|
||||||
g_assert(endptr == str + 3);
|
g_assert(endptr == str + 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2276,15 +2431,19 @@ static void test_qemu_strtosz_metric(void)
|
||||||
const char *str;
|
const char *str;
|
||||||
int err;
|
int err;
|
||||||
const char *endptr;
|
const char *endptr;
|
||||||
uint64_t res = 0xbaadf00d;
|
uint64_t res;
|
||||||
|
|
||||||
str = "12345k";
|
str = "12345k";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz_metric(str, &endptr, &res);
|
err = qemu_strtosz_metric(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 12345000);
|
g_assert_cmpint(res, ==, 12345000);
|
||||||
g_assert(endptr == str + 6);
|
g_assert(endptr == str + 6);
|
||||||
|
|
||||||
str = "12.345M";
|
str = "12.345M";
|
||||||
|
endptr = str;
|
||||||
|
res = 0xbaadf00d;
|
||||||
err = qemu_strtosz_metric(str, &endptr, &res);
|
err = qemu_strtosz_metric(str, &endptr, &res);
|
||||||
g_assert_cmpint(err, ==, 0);
|
g_assert_cmpint(err, ==, 0);
|
||||||
g_assert_cmpint(res, ==, 12345000);
|
g_assert_cmpint(res, ==, 12345000);
|
||||||
|
|
|
@ -2450,6 +2450,7 @@ void fuse_lowlevel_help(void)
|
||||||
printf(
|
printf(
|
||||||
" -o allow_root allow access by root\n"
|
" -o allow_root allow access by root\n"
|
||||||
" --socket-path=PATH path for the vhost-user socket\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"
|
" --fd=FDNUM fd number of vhost-user socket\n"
|
||||||
" --thread-pool-size=NUM thread pool size limit (default %d)\n",
|
" --thread-pool-size=NUM thread pool size limit (default %d)\n",
|
||||||
THREAD_POOL_SIZE);
|
THREAD_POOL_SIZE);
|
||||||
|
|
|
@ -362,7 +362,6 @@ static int do_strtosz(const char *nptr, const char **end,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*result = val;
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -371,6 +370,9 @@ out:
|
||||||
} else if (*endptr) {
|
} else if (*endptr) {
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
}
|
}
|
||||||
|
if (retval == 0) {
|
||||||
|
*result = val;
|
||||||
|
}
|
||||||
|
|
||||||
return retval;
|
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
|
* Helper function for error checking after strtol() and the like
|
||||||
*/
|
*/
|
||||||
static int check_strtox_error(const char *nptr, char *ep,
|
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);
|
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) {
|
if (endptr) {
|
||||||
*endptr = ep;
|
*endptr = ep;
|
||||||
}
|
}
|
||||||
|
@ -463,7 +478,7 @@ int qemu_strtoi(const char *nptr, const char **endptr, int base,
|
||||||
} else {
|
} else {
|
||||||
*result = lresult;
|
*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;
|
*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;
|
errno = 0;
|
||||||
*result = strtol(nptr, &ep, base);
|
*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) {
|
if (errno == ERANGE) {
|
||||||
*result = -1;
|
*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));
|
QEMU_BUILD_BUG_ON(sizeof(int64_t) != sizeof(long long));
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*result = strtoll(nptr, &ep, base);
|
*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) {
|
if (errno == ERANGE) {
|
||||||
*result = -1;
|
*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;
|
errno = 0;
|
||||||
*result = strtod(nptr, &ep);
|
*result = strtod(nptr, &ep);
|
||||||
return check_strtox_error(nptr, ep, endptr, errno);
|
return check_strtox_error(nptr, ep, endptr, false, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue