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_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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
6
configure
vendored
6
configure
vendored
@ -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
|
||||
|
@ -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.
|
||||
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.
|
||||
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).
|
||||
|
||||
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:
|
||||
|
||||
* 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
|
||||
=============================
|
||||
|
||||
|
@ -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
|
||||
=====
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 ===
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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', {})
|
||||
|
@ -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'
|
||||
|
@ -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))
|
||||
|
@ -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__':
|
||||
|
@ -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')
|
||||
|
@ -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 = {
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -208,6 +208,7 @@ class TestEnv(ContextManager['TestEnv']):
|
||||
('arm', 'virt'),
|
||||
('aarch64', 'virt'),
|
||||
('avr', 'mega2560'),
|
||||
('m68k', 'virt'),
|
||||
('rx', 'gdbsim-r5f562n8'),
|
||||
('tricore', 'tricore_testboard')
|
||||
)
|
||||
|
@ -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 := ,
|
||||
|
@ -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
|
||||
|
18
tests/tcg/aarch64/semicall.h
Normal file
18
tests/tcg/aarch64/semicall.h
Normal file
@ -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 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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
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)
|
||||
|
@ -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"
|
82
tests/tcg/multiarch/arm-compat-semi/semihosting.c
Normal file
82
tests/tcg/multiarch/arm-compat-semi/semihosting.c
Normal file
@ -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;
|
||||
}
|
22
tests/tcg/riscv64/semicall.h
Normal file
22
tests/tcg/riscv64/semicall.h
Normal file
@ -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(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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user