Doc and bug fixes

-----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAl+i3mkUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroNzSQf/WGDQnxXMt7gNVzWUyc8uest2qLGU
 OvJlbUJfVg7nbU+9FXP75sL5+KogwyU9znSZ9Jziib9PstRPNA32Wjhariv9fMls
 wed6c0yxyRN7ZNvis/CxMLQmctMuFZX9hILUGUVgq8uq7tNvA02nStb1sBwCywNO
 bkjR+ZgKRCh141EI/6GJ0JGbJ4gTEike26ss4pRXxHbDYQO9mw2vIRCw+DpRsoBY
 0QrT1IWwh9f7/Sm5a2kOfiRFTP2fmv4Y5udKLDzzkV3oLSMjlSvtn899MSdZ6Jv1
 tFAZnq7BxeaQgj/5a9lESRt+SmegdPUTYJh6V4UWRzEOZeFQcOT/qy2gXQ==
 =zGsk
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging

Doc and bug fixes

# gpg: Signature made Wed 04 Nov 2020 17:01:29 GMT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini-gitlab/tags/for-upstream:
  qapi, qemu-options: make all parsing visitors parse boolean options the same
  qtest: escape device name in device-introspect-test
  ivshmem-test: do not use short-form boolean option
  semihosting: fix order of initialization functions
  fuzz: fuzz offsets within pio/mmio regions
  fuzz: check the MR in the DMA callback
  fuzz: fix writing DMA patterns
  tests/qtest: Fix potential NULL pointer dereference in qos_build_main_args()
  configure: fix gio_libs reference
  meson: fix warning for bad sphinx-build
  tests/qtest/libqos/ahci.c: Avoid NULL dereference in ahci_exec()
  tests/qtest/libqtest.c: Check for setsockopt() failure
  meson: vhost-user-gpu/virtiofsd: use absolute path
  meson: use b_staticpic=false for meson >=0.56.0
  qtest: add a reproducer for LP#1878642
  hw/isa/lpc_ich9: Ignore reserved/invalid SCI IRQ
  scripts/oss-fuzz: rename bin/qemu-fuzz-i386
  exec: Remove dead code (CID 1432876)
  docs: expand sourceset documentation
  cutils: replace strdup with g_strdup

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-11-05 13:30:05 +00:00
commit 747c6b3811
27 changed files with 222 additions and 153 deletions

8
configure vendored
View File

@ -3499,7 +3499,7 @@ if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
# with pkg-config --static --libs data for gio-2.0 that is missing # with pkg-config --static --libs data for gio-2.0 that is missing
# -lblkid and will give a link error. # -lblkid and will give a link error.
write_c_skeleton write_c_skeleton
if compile_prog "" "gio_libs" ; then if compile_prog "" "$gio_libs" ; then
gio=yes gio=yes
else else
gio=no gio=no
@ -6961,6 +6961,10 @@ fi
mv $cross config-meson.cross mv $cross config-meson.cross
rm -rf meson-private meson-info meson-logs rm -rf meson-private meson-info meson-logs
unset staticpic
if ! version_ge "$($meson --version)" 0.56.0; then
staticpic=$(if test "$pie" = yes; then echo true; else echo false; fi)
fi
NINJA=$ninja $meson setup \ NINJA=$ninja $meson setup \
--prefix "$prefix" \ --prefix "$prefix" \
--libdir "$libdir" \ --libdir "$libdir" \
@ -6980,7 +6984,7 @@ NINJA=$ninja $meson setup \
-Dwerror=$(if test "$werror" = yes; then echo true; else echo false; fi) \ -Dwerror=$(if test "$werror" = yes; then echo true; else echo false; fi) \
-Dstrip=$(if test "$strip_opt" = yes; then echo true; else echo false; fi) \ -Dstrip=$(if test "$strip_opt" = yes; then echo true; else echo false; fi) \
-Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \ -Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \
-Db_staticpic=$(if test "$pie" = yes; then echo true; else echo false; fi) \ ${staticpic:+-Db_staticpic=$staticpic} \
-Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \ -Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \
-Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \ -Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \
-Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf \ -Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf \

View File

@ -9,6 +9,6 @@ if 'CONFIG_TOOLS' in config_host and 'CONFIG_VIRGL' in config_host \
configure_file(input: '50-qemu-gpu.json.in', configure_file(input: '50-qemu-gpu.json.in',
output: '50-qemu-gpu.json', output: '50-qemu-gpu.json',
configuration: { 'libexecdir' : get_option('libexecdir') }, configuration: { 'libexecdir' : get_option('prefix') / get_option('libexecdir') },
install_dir: qemu_datadir / 'vhost-user') install_dir: qemu_datadir / 'vhost-user')
endif endif

View File

@ -187,21 +187,23 @@ process for:
4) other data files, such as icons or desktop files 4) other data files, such as icons or desktop files
The source code is highly modularized, split across many files to
facilitate building of all of these components with as little duplicated
compilation as possible. The Meson "sourceset" functionality is used
to list the files and their dependency on various configuration
symbols.
All executables are built by default, except for some `contrib/` All executables are built by default, except for some `contrib/`
binaries that are known to fail to build on some platforms (for example binaries that are known to fail to build on some platforms (for example
32-bit or big-endian platforms). Tests are also built by default, 32-bit or big-endian platforms). Tests are also built by default,
though that might change in the future. though that might change in the future.
Various subsystems that are common to both tools and emulators have The source code is highly modularized, split across many files to
their own sourceset, for example `block_ss` for the block device subsystem, facilitate building of all of these components with as little duplicated
`chardev_ss` for the character device subsystem, etc. These sourcesets compilation as possible. Using the Meson "sourceset" functionality,
are then turned into static libraries as follows:: `meson.build` files group the source files in rules that are
enabled according to the available system libraries and to various
configuration symbols. Sourcesets belong to one of four groups:
Subsystem sourcesets:
Various subsystems that are common to both tools and emulators have
their own sourceset, for example `block_ss` for the block device subsystem,
`chardev_ss` for the character device subsystem, etc. These sourcesets
are then turned into static libraries as follows::
libchardev = static_library('chardev', chardev_ss.sources(), libchardev = static_library('chardev', chardev_ss.sources(),
name_suffix: 'fa', name_suffix: 'fa',
@ -209,61 +211,111 @@ are then turned into static libraries as follows::
chardev = declare_dependency(link_whole: libchardev) chardev = declare_dependency(link_whole: libchardev)
As of Meson 0.55.1, the special `.fa` suffix should be used for everything As of Meson 0.55.1, the special `.fa` suffix should be used for everything
that is used with `link_whole`, to ensure that the link flags are placed that is used with `link_whole`, to ensure that the link flags are placed
correctly in the command line. correctly in the command line.
Files linked into emulator targets there can be split into two distinct groups Target-independent emulator sourcesets:
of files, those which are independent of the QEMU emulation target and Various general purpose helper code is compiled only once and
those which are dependent on the QEMU emulation target. the .o files are linked into all output binaries that need it.
This includes error handling infrastructure, standard data structures,
platform portability wrapper functions, etc.
In the target-independent set lives various general purpose helper code, Target-independent code lives in the `common_ss`, `softmmu_ss` and
such as error handling infrastructure, standard data structures, `user_ss` sourcesets. `common_ss` is linked into all emulators,
platform portability wrapper functions, etc. This code can be compiled `softmmu_ss` only in system emulators, `user_ss` only in user-mode
once only and the .o files linked into all output binaries. emulators.
Target-independent code lives in the `common_ss`, `softmmu_ss` and
`user_ss` sourcesets. `common_ss` is linked into all emulators, `softmmu_ss`
only in system emulators, `user_ss` only in user-mode emulators.
In the target-dependent set lives CPU emulation, device emulation and Target-independent sourcesets must exercise particular care when using
much glue code. This sometimes also has to be compiled multiple times, `if_false` rules. The `if_false` rule will be used correctly when linking
once for each target being built. Target-dependent files are included emulator binaries; however, when *compiling* target-independent files
in the `specific_ss` sourceset. into .o files, Meson may need to pick *both* the `if_true` and
`if_false` sides to cater for targets that want either side. To
achieve that, you can add a special rule using the ``CONFIG_ALL``
symbol::
All binaries link with a static library `libqemuutil.a`, which is then # Some targets have CONFIG_ACPI, some don't, so this is not enough
linked to all the binaries. `libqemuutil.a` is built from several softmmu_ss.add(when: 'CONFIG_ACPI`, if_true: files('acpi.c'),
sourcesets; most of them however host generated code, and the only two if_false: files('acpi-stub.c'))
of general interest are `util_ss` and `stub_ss`.
# This is required as well:
softmmu_ss.add(when: 'CONFIG_ALL`, if_true: files('acpi-stub.c'))
Target-dependent emulator sourcesets:
In the target-dependent set lives CPU emulation, some device emulation and
much glue code. This sometimes also has to be compiled multiple times,
once for each target being built. Target-dependent files are included
in the `specific_ss` sourceset.
Each emulator also includes sources for files in the `hw/` and `target/`
subdirectories. The subdirectory used for each emulator comes
from the target's definition of ``TARGET_BASE_ARCH`` or (if missing)
``TARGET_ARCH``, as found in `default-configs/targets/*.mak`.
Each subdirectory in `hw/` adds one sourceset to the `hw_arch` dictionary,
for example::
arm_ss = ss.source_set()
arm_ss.add(files('boot.c'), fdt)
...
hw_arch += {'arm': arm_ss}
The sourceset is only used for system emulators.
Each subdirectory in `target/` instead should add one sourceset to each
of the `target_arch` and `target_softmmu_arch`, which are used respectively
for all emulators and for system emulators only. For example::
arm_ss = ss.source_set()
arm_softmmu_ss = ss.source_set()
...
target_arch += {'arm': arm_ss}
target_softmmu_arch += {'arm': arm_softmmu_ss}
Utility sourcesets:
All binaries link with a static library `libqemuutil.a`. This library
is built from several sourcesets; most of them however host generated
code, and the only two of general interest are `util_ss` and `stub_ss`.
The separation between these two is purely for documentation purposes.
`util_ss` contains generic utility files. Even though this code is only
linked in some binaries, sometimes it requires hooks only in some of
these and depend on other functions that are not fully implemented by
all QEMU binaries. `stub_ss` links dummy stubs that will only be linked
into the binary if the real implementation is not present. In a way,
the stubs can be thought of as a portable implementation of the weak
symbols concept.
The separation between these two is purely for documentation purposes.
`util_ss` contains generic utility files. Even though this code is only
linked in some binaries, sometimes it requires hooks only in some of
these and depend on other functions that are not fully implemented by
all QEMU binaries. `stub_ss` links dummy stubs that will only be linked
into the binary if the real implementation is not present. In a way,
the stubs can be thought of as a portable implementation of the weak
symbols concept.
The following files concur in the definition of which files are linked The following files concur in the definition of which files are linked
into each emulator: into each emulator:
`default-configs/*.mak` `default-configs/devices/*.mak`
The files under default-configs/ control what emulated hardware is built The files under `default-configs/devices/` control the boards and devices
into each QEMU system and userspace emulator targets. They merely contain that are built into each QEMU system emulation targets. They merely contain
a list of config variable definitions like the machines that should be a list of config variable definitions such as::
included. For example, default-configs/aarch64-softmmu.mak has::
include arm-softmmu.mak include arm-softmmu.mak
CONFIG_XLNX_ZYNQMP_ARM=y CONFIG_XLNX_ZYNQMP_ARM=y
CONFIG_XLNX_VERSAL=y CONFIG_XLNX_VERSAL=y
`*/Kconfig` `*/Kconfig`
These files are processed together with `default-configs/*.mak` and These files are processed together with `default-configs/devices/*.mak` and
describe the dependencies between various features, subsystems and describe the dependencies between various features, subsystems and
device models. They are described in kconfig.rst. device models. They are described in :ref:`kconfig`
These files rarely need changing unless new devices / hardware need to `default-configs/targets/*.mak`
be enabled for a particular system/userspace emulation target These files mostly define symbols that appear in the `*-config-target.h`
file for each emulator [#cfgtarget]_. However, the ``TARGET_ARCH``
and ``TARGET_BASE_ARCH`` will also be used to select the `hw/` and
`target/` subdirectories that are compiled into each target.
.. [#cfgtarget] This header is included by `qemu/osdep.h` when
compiling files from the target-specific sourcesets.
These files rarely need changing unless you are adding a completely
new target, or enabling new devices or hardware for a particular
system/userspace emulation target
Support scripts Support scripts

View File

@ -1,3 +1,5 @@
.. _kconfig:
================ ================
QEMU and Kconfig QEMU and Kconfig
================ ================

View File

@ -27,7 +27,8 @@ if sphinx_build.found()
build_docs = (sphinx_build_test_out.returncode() == 0) build_docs = (sphinx_build_test_out.returncode() == 0)
if not build_docs if not build_docs
warning('@0@ exists but it is either too old or uses too old a Python version'.format(get_option('sphinx_build'))) warning('@0@ is either too old or uses too old a Python version'
.format(sphinx_build.full_path()))
if get_option('docs').enabled() if get_option('docs').enabled()
error('Install a Python 3 version of python-sphinx') error('Install a Python 3 version of python-sphinx')
endif endif

View File

@ -29,6 +29,7 @@
*/ */
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h" #include "cpu.h"
#include "qapi/visitor.h" #include "qapi/visitor.h"
#include "qemu/range.h" #include "qemu/range.h"
@ -312,10 +313,12 @@ void ich9_generate_smi(void)
cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI); cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
} }
/* Returns -1 on error, IRQ number on success */
static int ich9_lpc_sci_irq(ICH9LPCState *lpc) static int ich9_lpc_sci_irq(ICH9LPCState *lpc)
{ {
switch (lpc->d.config[ICH9_LPC_ACPI_CTRL] & uint8_t sel = lpc->d.config[ICH9_LPC_ACPI_CTRL] &
ICH9_LPC_ACPI_CTRL_SCI_IRQ_SEL_MASK) { ICH9_LPC_ACPI_CTRL_SCI_IRQ_SEL_MASK;
switch (sel) {
case ICH9_LPC_ACPI_CTRL_9: case ICH9_LPC_ACPI_CTRL_9:
return 9; return 9;
case ICH9_LPC_ACPI_CTRL_10: case ICH9_LPC_ACPI_CTRL_10:
@ -328,6 +331,8 @@ static int ich9_lpc_sci_irq(ICH9LPCState *lpc)
return 21; return 21;
default: default:
/* reserved */ /* reserved */
qemu_log_mask(LOG_GUEST_ERROR,
"ICH9 LPC: SCI IRQ SEL #%u is reserved\n", sel);
break; break;
} }
return -1; return -1;
@ -459,7 +464,7 @@ ich9_lpc_pmbase_sci_update(ICH9LPCState *lpc)
{ {
uint32_t pm_io_base = pci_get_long(lpc->d.config + ICH9_LPC_PMBASE); uint32_t pm_io_base = pci_get_long(lpc->d.config + ICH9_LPC_PMBASE);
uint8_t acpi_cntl = pci_get_long(lpc->d.config + ICH9_LPC_ACPI_CTRL); uint8_t acpi_cntl = pci_get_long(lpc->d.config + ICH9_LPC_ACPI_CTRL);
uint8_t new_gsi; int new_gsi;
if (acpi_cntl & ICH9_LPC_ACPI_CTRL_ACPI_EN) { if (acpi_cntl & ICH9_LPC_ACPI_CTRL_ACPI_EN) {
pm_io_base &= ICH9_LPC_PMBASE_BASE_ADDRESS_MASK; pm_io_base &= ICH9_LPC_PMBASE_BASE_ADDRESS_MASK;
@ -470,6 +475,9 @@ ich9_lpc_pmbase_sci_update(ICH9LPCState *lpc)
ich9_pm_iospace_update(&lpc->pm, pm_io_base); ich9_pm_iospace_update(&lpc->pm, pm_io_base);
new_gsi = ich9_lpc_sci_irq(lpc); new_gsi = ich9_lpc_sci_irq(lpc);
if (new_gsi == -1) {
return;
}
if (lpc->sci_level && new_gsi != lpc->sci_gsi) { if (lpc->sci_level && new_gsi != lpc->sci_gsi) {
qemu_set_irq(lpc->pm.irq, 0); qemu_set_irq(lpc->pm.irq, 0);
lpc->sci_gsi = new_gsi; lpc->sci_gsi = new_gsi;

View File

@ -144,6 +144,7 @@ struct ICH9LPCState {
#define ICH9_LPC_PMBASE_BASE_ADDRESS_MASK Q35_MASK(32, 15, 7) #define ICH9_LPC_PMBASE_BASE_ADDRESS_MASK Q35_MASK(32, 15, 7)
#define ICH9_LPC_PMBASE_RTE 0x1 #define ICH9_LPC_PMBASE_RTE 0x1
#define ICH9_LPC_PMBASE_DEFAULT 0x1 #define ICH9_LPC_PMBASE_DEFAULT 0x1
#define ICH9_LPC_ACPI_CTRL 0x44 #define ICH9_LPC_ACPI_CTRL 0x44
#define ICH9_LPC_ACPI_CTRL_ACPI_EN 0x80 #define ICH9_LPC_ACPI_CTRL_ACPI_EN 0x80
#define ICH9_LPC_ACPI_CTRL_SCI_IRQ_SEL_MASK Q35_MASK(8, 2, 0) #define ICH9_LPC_ACPI_CTRL_SCI_IRQ_SEL_MASK Q35_MASK(8, 2, 0)

View File

@ -19,6 +19,8 @@ typedef struct QEnumLookup {
const char *qapi_enum_lookup(const QEnumLookup *lookup, int val); const char *qapi_enum_lookup(const QEnumLookup *lookup, int val);
int qapi_enum_parse(const QEnumLookup *lookup, const char *buf, int qapi_enum_parse(const QEnumLookup *lookup, const char *buf,
int def, Error **errp); int def, Error **errp);
bool qapi_bool_parse(const char *name, const char *value, bool *obj,
Error **errp);
int parse_qapi_name(const char *name, bool complete); int parse_qapi_name(const char *name, bool complete);

View File

@ -205,6 +205,7 @@ int qemu_pstrcmp0(const char **str1, const char **str2);
* as the prefix. For example, if `bindir` is `/usr/bin` and @dir is * as the prefix. For example, if `bindir` is `/usr/bin` and @dir is
* `/usr/share/qemu`, the function will append `../share/qemu` to the * `/usr/share/qemu`, the function will append `../share/qemu` to the
* directory that contains the running executable and return the result. * directory that contains the running executable and return the result.
* The returned string should be freed by the caller.
*/ */
char *get_relocated_path(const char *dir); char *get_relocated_path(const char *dir);

View File

@ -1,6 +1,6 @@
project('qemu', ['c'], meson_version: '>=0.55.0', project('qemu', ['c'], meson_version: '>=0.55.0',
default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11', default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11', 'b_colorout=auto'] +
'b_colorout=auto'], (meson.version().version_compare('>=0.56.0') ? [ 'b_staticpic=false' ] : []),
version: run_command('head', meson.source_root() / 'VERSION').stdout().strip()) version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
not_found = dependency('', required: false) not_found = dependency('', required: false)

View File

@ -368,7 +368,6 @@ opts_type_str(Visitor *v, const char *name, char **obj, Error **errp)
} }
/* mimics qemu-option.c::parse_option_bool() */
static bool static bool
opts_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) opts_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
{ {
@ -379,19 +378,8 @@ opts_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
if (!opt) { if (!opt) {
return false; return false;
} }
if (opt->str) { if (opt->str) {
if (strcmp(opt->str, "on") == 0 || if (!qapi_bool_parse(opt->name, opt->str, obj, errp)) {
strcmp(opt->str, "yes") == 0 ||
strcmp(opt->str, "y") == 0) {
*obj = true;
} else if (strcmp(opt->str, "off") == 0 ||
strcmp(opt->str, "no") == 0 ||
strcmp(opt->str, "n") == 0) {
*obj = false;
} else {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
"on|yes|y|off|no|n");
return false; return false;
} }
} else { } else {

View File

@ -13,6 +13,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/ctype.h" #include "qemu/ctype.h"
#include "qapi/qmp/qerror.h"
const char *qapi_enum_lookup(const QEnumLookup *lookup, int val) const char *qapi_enum_lookup(const QEnumLookup *lookup, int val)
{ {
@ -40,6 +41,28 @@ int qapi_enum_parse(const QEnumLookup *lookup, const char *buf,
return def; return def;
} }
bool qapi_bool_parse(const char *name, const char *value, bool *obj, Error **errp)
{
if (g_str_equal(value, "on") ||
g_str_equal(value, "yes") ||
g_str_equal(value, "true") ||
g_str_equal(value, "y")) {
*obj = true;
return true;
}
if (g_str_equal(value, "off") ||
g_str_equal(value, "no") ||
g_str_equal(value, "false") ||
g_str_equal(value, "n")) {
*obj = false;
return true;
}
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name,
"'on' or 'off'");
return false;
}
/* /*
* Parse a valid QAPI name from @str. * Parse a valid QAPI name from @str.
* A valid name consists of letters, digits, hyphen and underscore. * A valid name consists of letters, digits, hyphen and underscore.

View File

@ -512,11 +512,7 @@ static bool qobject_input_type_bool_keyval(Visitor *v, const char *name,
return false; return false;
} }
if (!strcmp(str, "on")) { if (!qapi_bool_parse(name, str, obj, NULL)) {
*obj = true;
} else if (!strcmp(str, "off")) {
*obj = false;
} else {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
full_name(qiv, name), "'on' or 'off'"); full_name(qiv, name), "'on' or 'off'");
return false; return false;

View File

@ -332,22 +332,7 @@ static bool parse_type_bool(Visitor *v, const char *name, bool *obj,
StringInputVisitor *siv = to_siv(v); StringInputVisitor *siv = to_siv(v);
assert(siv->lm == LM_NONE); assert(siv->lm == LM_NONE);
if (!strcasecmp(siv->string, "on") || return qapi_bool_parse(name ? name : "null", siv->string, obj, errp);
!strcasecmp(siv->string, "yes") ||
!strcasecmp(siv->string, "true")) {
*obj = true;
return true;
}
if (!strcasecmp(siv->string, "off") ||
!strcasecmp(siv->string, "no") ||
!strcasecmp(siv->string, "false")) {
*obj = false;
return true;
}
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
"boolean");
return false;
} }
static bool parse_type_str(Visitor *v, const char *name, char **obj, static bool parse_type_str(Visitor *v, const char *name, char **obj,

View File

@ -91,7 +91,7 @@ make "-j$(nproc)" qemu-fuzz-i386 V=1
# Copy over the datadir # Copy over the datadir
cp -r ../pc-bios/ "$DEST_DIR/pc-bios" cp -r ../pc-bios/ "$DEST_DIR/pc-bios"
cp "./qemu-fuzz-i386" "$DEST_DIR/bin/" cp "./qemu-fuzz-i386" "$DEST_DIR/bin/qemu-fuzz-i386.base"
# Run the fuzzer with no arguments, to print the help-string and get the list # Run the fuzzer with no arguments, to print the help-string and get the list
# of available fuzz-targets. Copy over the qemu-fuzz-i386, naming it according # of available fuzz-targets. Copy over the qemu-fuzz-i386, naming it according
@ -104,7 +104,7 @@ do
# that are thin wrappers around this target that set the required # that are thin wrappers around this target that set the required
# environment variables according to predefined configs. # environment variables according to predefined configs.
if [ "$target" != "generic-fuzz" ]; then if [ "$target" != "generic-fuzz" ]; then
ln "$DEST_DIR/bin/qemu-fuzz-i386" \ ln "$DEST_DIR/bin/qemu-fuzz-i386.base" \
"$DEST_DIR/qemu-fuzz-i386-target-$target" "$DEST_DIR/qemu-fuzz-i386-target-$target"
fi fi
done done

View File

@ -2723,22 +2723,14 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
static bool prepare_mmio_access(MemoryRegion *mr) static bool prepare_mmio_access(MemoryRegion *mr)
{ {
bool unlocked = !qemu_mutex_iothread_locked();
bool release_lock = false; bool release_lock = false;
if (unlocked) { if (!qemu_mutex_iothread_locked()) {
qemu_mutex_lock_iothread(); qemu_mutex_lock_iothread();
unlocked = false;
release_lock = true; release_lock = true;
} }
if (mr->flush_coalesced_mmio) { if (mr->flush_coalesced_mmio) {
if (unlocked) {
qemu_mutex_lock_iothread();
}
qemu_flush_coalesced_mmio_buffer(); qemu_flush_coalesced_mmio_buffer();
if (unlocked) {
qemu_mutex_unlock_iothread();
}
} }
return release_lock; return release_lock;

View File

@ -4284,9 +4284,6 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_opts_foreach(qemu_find_opts("mon"), qemu_opts_foreach(qemu_find_opts("mon"),
mon_init_func, NULL, &error_fatal); mon_init_func, NULL, &error_fatal);
/* connect semihosting console input if requested */
qemu_semihosting_console_init();
if (foreach_device_config(DEV_SERIAL, serial_parse) < 0) if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
exit(1); exit(1);
if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0) if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
@ -4296,6 +4293,7 @@ void qemu_init(int argc, char **argv, char **envp)
/* now chardevs have been created we may have semihosting to connect */ /* now chardevs have been created we may have semihosting to connect */
qemu_semihosting_connect_chardevs(); qemu_semihosting_connect_chardevs();
qemu_semihosting_console_init();
/* If no default VGA is requested, the default is "none". */ /* If no default VGA is requested, the default is "none". */
if (default_vga) { if (default_vga) {

View File

@ -104,7 +104,8 @@ static QList *device_type_list(QTestState *qts, bool abstract)
static void test_one_device(QTestState *qts, const char *type) static void test_one_device(QTestState *qts, const char *type)
{ {
QDict *resp; QDict *resp;
char *help; char *help, *escaped;
GRegex *comma;
g_test_message("Testing device '%s'", type); g_test_message("Testing device '%s'", type);
@ -113,8 +114,13 @@ static void test_one_device(QTestState *qts, const char *type)
type); type);
qobject_unref(resp); qobject_unref(resp);
help = qtest_hmp(qts, "device_add \"%s,help\"", type); comma = g_regex_new(",", 0, 0, NULL);
escaped = g_regex_replace_literal(comma, type, -1, 0, ",,", 0, NULL);
g_regex_unref(comma);
help = qtest_hmp(qts, "device_add \"%s,help\"", escaped);
g_free(help); g_free(help);
g_free(escaped);
} }
static void test_device_intro_list(void) static void test_device_intro_list(void)

View File

@ -34,6 +34,19 @@ static void test_lp1878263_megasas_zero_iov_cnt(void)
qtest_quit(s); qtest_quit(s);
} }
static void test_lp1878642_pci_bus_get_irq_level_assert(void)
{
QTestState *s;
s = qtest_init("-M pc-q35-5.0 "
"-nographic -monitor none -serial none "
"-d guest_errors -trace pci*");
qtest_outl(s, 0xcf8, 0x8400f841);
qtest_outl(s, 0xcfc, 0xebed205d);
qtest_outl(s, 0x5d02, 0xebed205d);
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
const char *arch = qtest_get_arch(); const char *arch = qtest_get_arch();
@ -43,6 +56,8 @@ int main(int argc, char **argv)
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
qtest_add_func("fuzz/test_lp1878263_megasas_zero_iov_cnt", qtest_add_func("fuzz/test_lp1878263_megasas_zero_iov_cnt",
test_lp1878263_megasas_zero_iov_cnt); test_lp1878263_megasas_zero_iov_cnt);
qtest_add_func("fuzz/test_lp1878642_pci_bus_get_irq_level_assert",
test_lp1878642_pci_bus_get_irq_level_assert);
} }
return g_test_run(); return g_test_run();

View File

@ -192,7 +192,7 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)
*/ */
if (dma_patterns->len == 0 if (dma_patterns->len == 0
|| len == 0 || len == 0
/* || mr != MACHINE(qdev_get_machine())->ram */ || mr != current_machine->ram
|| is_write || is_write
|| addr > current_machine->ram_size) { || addr > current_machine->ram_size) {
return; return;
@ -229,10 +229,10 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)
address_range ar = {addr, len}; address_range ar = {addr, len};
g_array_append_val(dma_regions, ar); g_array_append_val(dma_regions, ar);
pattern p = g_array_index(dma_patterns, pattern, dma_pattern_index); pattern p = g_array_index(dma_patterns, pattern, dma_pattern_index);
void *buf = pattern_alloc(p, ar.size); void *buf_base = pattern_alloc(p, ar.size);
void *buf = buf_base;
hwaddr l, addr1; hwaddr l, addr1;
MemoryRegion *mr1; MemoryRegion *mr1;
uint8_t *ram_ptr;
while (len > 0) { while (len > 0) {
l = len; l = len;
mr1 = address_space_translate(first_cpu->as, mr1 = address_space_translate(first_cpu->as,
@ -244,30 +244,27 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)
l = memory_access_size(mr1, l, addr1); l = memory_access_size(mr1, l, addr1);
} else { } else {
/* ROM/RAM case */ /* ROM/RAM case */
ram_ptr = qemu_map_ram_ptr(mr1->ram_block, addr1); if (qtest_log_enabled) {
memcpy(ram_ptr, buf, l); /*
break; * With QTEST_LOG, use a normal, slow QTest memwrite. Prefix the log
* that will be written by qtest.c with a DMA tag, so we can reorder
* the resulting QTest trace so the DMA fills precede the last PIO/MMIO
* command.
*/
fprintf(stderr, "[DMA] ");
if (double_fetch) {
fprintf(stderr, "[DOUBLE-FETCH] ");
}
fflush(stderr);
}
qtest_memwrite(qts_global, addr, buf, l);
} }
len -= l; len -= l;
buf += l; buf += l;
addr += l; addr += l;
} }
if (qtest_log_enabled) { g_free(buf_base);
/*
* With QTEST_LOG, use a normal, slow QTest memwrite. Prefix the log
* that will be written by qtest.c with a DMA tag, so we can reorder
* the resulting QTest trace so the DMA fills precede the last PIO/MMIO
* command.
*/
fprintf(stderr, "[DMA] ");
if (double_fetch) {
fprintf(stderr, "[DOUBLE-FETCH] ");
}
fflush(stderr);
}
qtest_memwrite(qts_global, ar.addr, buf, ar.size);
g_free(buf);
/* Increment the index of the pattern for the next DMA access */ /* Increment the index of the pattern for the next DMA access */
dma_pattern_index = (dma_pattern_index + 1) % dma_patterns->len; dma_pattern_index = (dma_pattern_index + 1) % dma_patterns->len;
@ -301,6 +298,11 @@ static bool get_io_address(address_range *result, AddressSpace *as,
} while (cb_info.index != index && !cb_info.found); } while (cb_info.index != index && !cb_info.found);
*result = cb_info.result; *result = cb_info.result;
if (result->size) {
offset = offset % result->size;
result->addr += offset;
result->size -= offset;
}
return cb_info.found; return cb_info.found;
} }

View File

@ -70,7 +70,7 @@ static GString *qos_build_main_args(void)
{ {
char **path = fuzz_path_vec; char **path = fuzz_path_vec;
QOSGraphNode *test_node; QOSGraphNode *test_node;
GString *cmd_line = g_string_new(path[0]); GString *cmd_line;
void *test_arg; void *test_arg;
if (!path) { if (!path) {
@ -79,6 +79,7 @@ static GString *qos_build_main_args(void)
} }
/* Before test */ /* Before test */
cmd_line = g_string_new(path[0]);
current_path = path; current_path = path;
test_node = qos_graph_get_node(path[(g_strv_length(path) - 1)]); test_node = qos_graph_get_node(path[(g_strv_length(path) - 1)]);
test_arg = test_node->u.test.arg; test_arg = test_node->u.test.arg;

View File

@ -135,7 +135,7 @@ static void setup_vm_cmd(IVState *s, const char *cmd, bool msix)
static void setup_vm(IVState *s) static void setup_vm(IVState *s)
{ {
char *cmd = g_strdup_printf("-object memory-backend-file" char *cmd = g_strdup_printf("-object memory-backend-file"
",id=mb1,size=1M,share,mem-path=/dev/shm%s" ",id=mb1,size=1M,share=on,mem-path=/dev/shm%s"
" -device ivshmem-plain,memdev=mb1", tmpshm); " -device ivshmem-plain,memdev=mb1", tmpshm);
setup_vm_cmd(s, cmd, false); setup_vm_cmd(s, cmd, false);

View File

@ -637,10 +637,13 @@ void ahci_exec(AHCIQState *ahci, uint8_t port,
AHCICommand *cmd; AHCICommand *cmd;
int rc; int rc;
AHCIOpts *opts; AHCIOpts *opts;
uint64_t buffer_in;
opts = g_memdup((opts_in == NULL ? &default_opts : opts_in), opts = g_memdup((opts_in == NULL ? &default_opts : opts_in),
sizeof(AHCIOpts)); sizeof(AHCIOpts));
buffer_in = opts->buffer;
/* No guest buffer provided, create one. */ /* No guest buffer provided, create one. */
if (opts->size && !opts->buffer) { if (opts->size && !opts->buffer) {
opts->buffer = ahci_alloc(ahci, opts->size); opts->buffer = ahci_alloc(ahci, opts->size);
@ -686,7 +689,7 @@ void ahci_exec(AHCIQState *ahci, uint8_t port,
g_assert_cmpint(rc, ==, 0); g_assert_cmpint(rc, ==, 0);
} }
ahci_command_free(cmd); ahci_command_free(cmd);
if (opts->buffer != opts_in->buffer) { if (opts->buffer != buffer_in) {
ahci_free(ahci, opts->buffer); ahci_free(ahci, opts->buffer);
} }
g_free(opts); g_free(opts);

View File

@ -110,8 +110,13 @@ static int socket_accept(int sock)
struct timeval timeout = { .tv_sec = SOCKET_TIMEOUT, struct timeval timeout = { .tv_sec = SOCKET_TIMEOUT,
.tv_usec = 0 }; .tv_usec = 0 };
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, if (qemu_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
sizeof(timeout)); (void *)&timeout, sizeof(timeout))) {
fprintf(stderr, "%s failed to set SO_RCVTIMEO: %s\n",
__func__, strerror(errno));
close(sock);
return -1;
}
do { do {
addrlen = sizeof(addr); addrlen = sizeof(addr);

View File

@ -15,5 +15,5 @@ executable('virtiofsd', files(
configure_file(input: '50-qemu-virtiofsd.json.in', configure_file(input: '50-qemu-virtiofsd.json.in',
output: '50-qemu-virtiofsd.json', output: '50-qemu-virtiofsd.json',
configuration: { 'libexecdir' : get_option('libexecdir') }, configuration: { 'libexecdir' : get_option('prefix') / get_option('libexecdir') },
install_dir: qemu_datadir / 'vhost-user') install_dir: qemu_datadir / 'vhost-user')

View File

@ -937,7 +937,7 @@ char *get_relocated_path(const char *dir)
/* Fail if qemu_init_exec_dir was not called. */ /* Fail if qemu_init_exec_dir was not called. */
assert(exec_dir[0]); assert(exec_dir[0]);
if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) { if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
return strdup(dir); return g_strdup(dir);
} }
result = g_string_new(exec_dir); result = g_string_new(exec_dir);

View File

@ -96,21 +96,6 @@ const char *get_opt_value(const char *p, char **value)
return offset; return offset;
} }
static bool parse_option_bool(const char *name, const char *value, bool *ret,
Error **errp)
{
if (!strcmp(value, "on")) {
*ret = 1;
} else if (!strcmp(value, "off")) {
*ret = 0;
} else {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
name, "'on' or 'off'");
return false;
}
return true;
}
static bool parse_option_number(const char *name, const char *value, static bool parse_option_number(const char *name, const char *value,
uint64_t *ret, Error **errp) uint64_t *ret, Error **errp)
{ {
@ -363,7 +348,7 @@ static bool qemu_opt_get_bool_helper(QemuOpts *opts, const char *name,
if (opt == NULL) { if (opt == NULL) {
def_val = find_default_by_name(opts, name); def_val = find_default_by_name(opts, name);
if (def_val) { if (def_val) {
parse_option_bool(name, def_val, &ret, &error_abort); qapi_bool_parse(name, def_val, &ret, &error_abort);
} }
return ret; return ret;
} }
@ -471,8 +456,7 @@ static bool qemu_opt_parse(QemuOpt *opt, Error **errp)
/* nothing */ /* nothing */
return true; return true;
case QEMU_OPT_BOOL: case QEMU_OPT_BOOL:
return parse_option_bool(opt->name, opt->str, &opt->value.boolean, return qapi_bool_parse(opt->name, opt->str, &opt->value.boolean, errp);
errp);
case QEMU_OPT_NUMBER: case QEMU_OPT_NUMBER:
return parse_option_number(opt->name, opt->str, &opt->value.uint, return parse_option_number(opt->name, opt->str, &opt->value.uint,
errp); errp);