* kvm: enable dirty ring for arm64
* target/i386: new features * target/i386: AVX fixes * configure: create a python venv unconditionally * meson: bump to 0.63.0 and move tests from configure * meson: Pass -j option to sphinx * drop support for Python 3.6 * fix check-python-tox * fix "make clean" in the source directory -----BEGIN PGP SIGNATURE----- iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmRmDYQUHHBib256aW5p QHJlZGhhdC5jb20ACgkQv/vSX3jHroOXSwf/WKmYPe09yHfxfVSFsSz83QpB3e+f KJx6FdyMMt26ZQJpcqorobrDV23R8FyxngXPkwoxqobAEtXB/AH0/S/u8RUZ46Qt IrF8FXr4ZdyLW7CW6nmIejmlul0iRmFD7D98E6dZ3QXfype3Ifra7gG74spZ1B44 ZNvaomJKUK8Ga8rbChs9KtgrxlOC5q8IfTWF5ZExmZszPC9NRnZmU5Oncnuwek9T Ic6zDPoAeF3jDtovZhxg1HAB9e/ENZX/V9NjO92yZa8u/TITQ88l4tJctf7uiLxO 2oGY12ln8i//pbjyUe4iM+bNh5+reAChEI8iv7WxEsj9s2HBUJ68f3tpbQ== =Zg00 -----END PGP SIGNATURE----- Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging * kvm: enable dirty ring for arm64 * target/i386: new features * target/i386: AVX fixes * configure: create a python venv unconditionally * meson: bump to 0.63.0 and move tests from configure * meson: Pass -j option to sphinx * drop support for Python 3.6 * fix check-python-tox * fix "make clean" in the source directory # -----BEGIN PGP SIGNATURE----- # # iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmRmDYQUHHBib256aW5p # QHJlZGhhdC5jb20ACgkQv/vSX3jHroOXSwf/WKmYPe09yHfxfVSFsSz83QpB3e+f # KJx6FdyMMt26ZQJpcqorobrDV23R8FyxngXPkwoxqobAEtXB/AH0/S/u8RUZ46Qt # IrF8FXr4ZdyLW7CW6nmIejmlul0iRmFD7D98E6dZ3QXfype3Ifra7gG74spZ1B44 # ZNvaomJKUK8Ga8rbChs9KtgrxlOC5q8IfTWF5ZExmZszPC9NRnZmU5Oncnuwek9T # Ic6zDPoAeF3jDtovZhxg1HAB9e/ENZX/V9NjO92yZa8u/TITQ88l4tJctf7uiLxO # 2oGY12ln8i//pbjyUe4iM+bNh5+reAChEI8iv7WxEsj9s2HBUJ68f3tpbQ== # =Zg00 # -----END PGP SIGNATURE----- # gpg: Signature made Thu 18 May 2023 04:35:32 AM PDT # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [undefined] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # 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 * tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (68 commits) docs/devel: update build system docs configure: remove unnecessary check configure: reorder option parsing code configure: remove unnecessary mkdir configure: do not rerun the tests with -Werror configure: remove compiler sanity check build: move --disable-debug-info to meson build: move compiler version check to meson build: move remaining compiler flag tests to meson build: move warning flag selection to meson build: move stack protector flag selection to meson build: move coroutine backend selection to meson build: move SafeStack tests to meson build: move sanitizer tests to meson meson: prepare move of QEMU_CFLAGS to meson configure, meson: move --enable-modules to Meson configure: remove pkg-config functions build: move glib detection and workarounds to meson meson: drop unnecessary declare_dependency() meson: add more version numbers to the summary ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
f0b95ab6b8
@ -12,12 +12,12 @@
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --enable-werror --disable-docs --enable-fdt=system
|
||||
${LD_JOBS:+--meson=git} ${TARGETS:+--target-list="$TARGETS"}
|
||||
${TARGETS:+--target-list="$TARGETS"}
|
||||
$CONFIGURE_ARGS ||
|
||||
{ cat config.log meson-logs/meson-log.txt && exit 1; }
|
||||
- if test -n "$LD_JOBS";
|
||||
then
|
||||
../meson/meson.py configure . -Dbackend_max_links="$LD_JOBS" ;
|
||||
pyvenv/bin/meson configure . -Dbackend_max_links="$LD_JOBS" ;
|
||||
fi || exit 1;
|
||||
- make -j"$JOBS"
|
||||
- if test -n "$MAKE_CHECK_ARGS";
|
||||
|
@ -103,7 +103,7 @@ crash-test-debian:
|
||||
script:
|
||||
- cd build
|
||||
- make NINJA=":" check-venv
|
||||
- tests/venv/bin/python3 scripts/device-crash-test -q --tcg-only ./qemu-system-i386
|
||||
- pyvenv/bin/python3 scripts/device-crash-test -q --tcg-only ./qemu-system-i386
|
||||
|
||||
build-system-fedora:
|
||||
extends:
|
||||
@ -146,8 +146,8 @@ crash-test-fedora:
|
||||
script:
|
||||
- cd build
|
||||
- make NINJA=":" check-venv
|
||||
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-ppc
|
||||
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-riscv32
|
||||
- pyvenv/bin/python3 scripts/device-crash-test -q ./qemu-system-ppc
|
||||
- pyvenv/bin/python3 scripts/device-crash-test -q ./qemu-system-riscv32
|
||||
|
||||
build-system-centos:
|
||||
extends:
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -49,9 +49,6 @@
|
||||
[submodule "roms/qboot"]
|
||||
path = roms/qboot
|
||||
url = https://gitlab.com/qemu-project/qboot.git
|
||||
[submodule "meson"]
|
||||
path = meson
|
||||
url = https://gitlab.com/qemu-project/meson.git
|
||||
[submodule "roms/vbootrom"]
|
||||
path = roms/vbootrom
|
||||
url = https://gitlab.com/qemu-project/vbootrom.git
|
||||
|
6
Makefile
6
Makefile
@ -26,7 +26,7 @@ quiet-command-run = $(if $(V),,$(if $2,printf " %-7s %s\n" $2 $3 && ))$1
|
||||
quiet-@ = $(if $(V),,@)
|
||||
quiet-command = $(quiet-@)$(call quiet-command-run,$1,$2,$3)
|
||||
|
||||
UNCHECKED_GOALS := %clean TAGS cscope ctags dist \
|
||||
UNCHECKED_GOALS := TAGS gtags cscope ctags dist \
|
||||
help check-help print-% \
|
||||
docker docker-% vm-help vm-test vm-build-%
|
||||
|
||||
@ -176,10 +176,8 @@ plugins:
|
||||
endif # $(CONFIG_PLUGIN)
|
||||
|
||||
else # config-host.mak does not exist
|
||||
config-host.mak:
|
||||
ifneq ($(filter-out $(UNCHECKED_GOALS),$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fail))
|
||||
@echo "Please call configure before running make!"
|
||||
@exit 1
|
||||
$(error Please call configure before running make)
|
||||
endif
|
||||
endif # config-host.mak does not exist
|
||||
|
||||
|
@ -1361,6 +1361,10 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
||||
*/
|
||||
if (kvm_state->kvm_dirty_ring_size) {
|
||||
kvm_dirty_ring_reap_locked(kvm_state, NULL);
|
||||
if (kvm_state->kvm_dirty_ring_with_bitmap) {
|
||||
kvm_slot_sync_dirty_pages(mem);
|
||||
kvm_slot_get_dirty_log(kvm_state, mem);
|
||||
}
|
||||
} else {
|
||||
kvm_slot_get_dirty_log(kvm_state, mem);
|
||||
}
|
||||
@ -1458,6 +1462,69 @@ static int kvm_dirty_ring_reaper_init(KVMState *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_dirty_ring_init(KVMState *s)
|
||||
{
|
||||
uint32_t ring_size = s->kvm_dirty_ring_size;
|
||||
uint64_t ring_bytes = ring_size * sizeof(struct kvm_dirty_gfn);
|
||||
unsigned int capability = KVM_CAP_DIRTY_LOG_RING;
|
||||
int ret;
|
||||
|
||||
s->kvm_dirty_ring_size = 0;
|
||||
s->kvm_dirty_ring_bytes = 0;
|
||||
|
||||
/* Bail if the dirty ring size isn't specified */
|
||||
if (!ring_size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the max supported pages. Fall back to dirty logging mode
|
||||
* if the dirty ring isn't supported.
|
||||
*/
|
||||
ret = kvm_vm_check_extension(s, capability);
|
||||
if (ret <= 0) {
|
||||
capability = KVM_CAP_DIRTY_LOG_RING_ACQ_REL;
|
||||
ret = kvm_vm_check_extension(s, capability);
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
warn_report("KVM dirty ring not available, using bitmap method");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ring_bytes > ret) {
|
||||
error_report("KVM dirty ring size %" PRIu32 " too big "
|
||||
"(maximum is %ld). Please use a smaller value.",
|
||||
ring_size, (long)ret / sizeof(struct kvm_dirty_gfn));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = kvm_vm_enable_cap(s, capability, 0, ring_bytes);
|
||||
if (ret) {
|
||||
error_report("Enabling of KVM dirty ring failed: %s. "
|
||||
"Suggested minimum value is 1024.", strerror(-ret));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Enable the backup bitmap if it is supported */
|
||||
ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP);
|
||||
if (ret > 0) {
|
||||
ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP, 0);
|
||||
if (ret) {
|
||||
error_report("Enabling of KVM dirty ring's backup bitmap failed: "
|
||||
"%s. ", strerror(-ret));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
s->kvm_dirty_ring_with_bitmap = true;
|
||||
}
|
||||
|
||||
s->kvm_dirty_ring_size = ring_size;
|
||||
s->kvm_dirty_ring_bytes = ring_bytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void kvm_region_add(MemoryListener *listener,
|
||||
MemoryRegionSection *section)
|
||||
{
|
||||
@ -1563,7 +1630,7 @@ static void kvm_log_sync(MemoryListener *listener,
|
||||
kvm_slots_unlock();
|
||||
}
|
||||
|
||||
static void kvm_log_sync_global(MemoryListener *l)
|
||||
static void kvm_log_sync_global(MemoryListener *l, bool last_stage)
|
||||
{
|
||||
KVMMemoryListener *kml = container_of(l, KVMMemoryListener, listener);
|
||||
KVMState *s = kvm_state;
|
||||
@ -1582,6 +1649,12 @@ static void kvm_log_sync_global(MemoryListener *l)
|
||||
mem = &kml->slots[i];
|
||||
if (mem->memory_size && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
|
||||
kvm_slot_sync_dirty_pages(mem);
|
||||
|
||||
if (s->kvm_dirty_ring_with_bitmap && last_stage &&
|
||||
kvm_slot_get_dirty_log(s, mem)) {
|
||||
kvm_slot_sync_dirty_pages(mem);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is not needed by KVM_GET_DIRTY_LOG because the
|
||||
* ioctl will unconditionally overwrite the whole region.
|
||||
@ -2521,35 +2594,9 @@ static int kvm_init(MachineState *ms)
|
||||
* Enable KVM dirty ring if supported, otherwise fall back to
|
||||
* dirty logging mode
|
||||
*/
|
||||
if (s->kvm_dirty_ring_size > 0) {
|
||||
uint64_t ring_bytes;
|
||||
|
||||
ring_bytes = s->kvm_dirty_ring_size * sizeof(struct kvm_dirty_gfn);
|
||||
|
||||
/* Read the max supported pages */
|
||||
ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING);
|
||||
if (ret > 0) {
|
||||
if (ring_bytes > ret) {
|
||||
error_report("KVM dirty ring size %" PRIu32 " too big "
|
||||
"(maximum is %ld). Please use a smaller value.",
|
||||
s->kvm_dirty_ring_size,
|
||||
(long)ret / sizeof(struct kvm_dirty_gfn));
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING, 0, ring_bytes);
|
||||
if (ret) {
|
||||
error_report("Enabling of KVM dirty ring failed: %s. "
|
||||
"Suggested minimum value is 1024.", strerror(-ret));
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->kvm_dirty_ring_bytes = ring_bytes;
|
||||
} else {
|
||||
warn_report("KVM dirty ring not available, using bitmap method");
|
||||
s->kvm_dirty_ring_size = 0;
|
||||
}
|
||||
ret = kvm_dirty_ring_init(s);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3710,6 +3757,7 @@ static void kvm_accel_instance_init(Object *obj)
|
||||
s->kernel_irqchip_split = ON_OFF_AUTO_AUTO;
|
||||
/* KVM dirty ring is by default off */
|
||||
s->kvm_dirty_ring_size = 0;
|
||||
s->kvm_dirty_ring_with_bitmap = false;
|
||||
s->notify_vmexit = NOTIFY_VMEXIT_OPTION_RUN;
|
||||
s->notify_window = 0;
|
||||
s->xen_version = 0;
|
||||
|
@ -72,11 +72,13 @@ static void rr_kick_next_cpu(void)
|
||||
{
|
||||
CPUState *cpu;
|
||||
do {
|
||||
cpu = qatomic_mb_read(&rr_current_cpu);
|
||||
cpu = qatomic_read(&rr_current_cpu);
|
||||
if (cpu) {
|
||||
cpu_exit(cpu);
|
||||
}
|
||||
} while (cpu != qatomic_mb_read(&rr_current_cpu));
|
||||
/* Finish kicking this cpu before reading again. */
|
||||
smp_mb();
|
||||
} while (cpu != qatomic_read(&rr_current_cpu));
|
||||
}
|
||||
|
||||
static void rr_kick_thread(void *opaque)
|
||||
@ -241,8 +243,9 @@ static void *rr_cpu_thread_fn(void *arg)
|
||||
}
|
||||
|
||||
while (cpu && cpu_work_list_empty(cpu) && !cpu->exit_request) {
|
||||
|
||||
/* Store rr_current_cpu before evaluating cpu_can_run(). */
|
||||
qatomic_mb_set(&rr_current_cpu, cpu);
|
||||
|
||||
current_cpu = cpu;
|
||||
|
||||
qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
|
||||
@ -280,7 +283,7 @@ static void *rr_cpu_thread_fn(void *arg)
|
||||
cpu = CPU_NEXT(cpu);
|
||||
} /* while (cpu && !cpu->exit_request).. */
|
||||
|
||||
/* Does not need qatomic_mb_set because a spurious wakeup is okay. */
|
||||
/* Does not need a memory barrier because a spurious wakeup is okay. */
|
||||
qatomic_set(&rr_current_cpu, NULL);
|
||||
|
||||
if (cpu && cpu->exit_request) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
# This Makefile example is fairly independent from the main makefile
|
||||
# so users can take and adapt it for their build. We only really
|
||||
# include config-host.mak so we don't have to repeat probing for
|
||||
# cflags that the main configure has already done for us.
|
||||
# programs that the main configure has already done for us.
|
||||
#
|
||||
|
||||
BUILD_DIR := $(CURDIR)/../..
|
||||
@ -26,9 +26,8 @@ SONAMES := $(addsuffix .so,$(addprefix lib,$(NAMES)))
|
||||
|
||||
# The main QEMU uses Glib extensively so it's perfectly fine to use it
|
||||
# in plugins (which many example do).
|
||||
CFLAGS = $(GLIB_CFLAGS)
|
||||
CFLAGS += -fPIC -Wall $(filter -W%, $(QEMU_CFLAGS))
|
||||
CFLAGS += $(if $(findstring no-psabi,$(QEMU_CFLAGS)),-Wpsabi)
|
||||
CFLAGS := $(shell $(PKG_CONFIG) --cflags glib-2.0)
|
||||
CFLAGS += -fPIC -Wall
|
||||
CFLAGS += $(if $(CONFIG_DEBUG_TCG), -ggdb -O0)
|
||||
CFLAGS += -I$(SRC_PATH)/include/qemu
|
||||
|
||||
|
@ -98,7 +98,7 @@ Python runtime
|
||||
option of the ``configure`` script to point QEMU to a supported
|
||||
version of the Python runtime.
|
||||
|
||||
As of QEMU |version|, the minimum supported version of Python is 3.6.
|
||||
As of QEMU |version|, the minimum supported version of Python is 3.7.
|
||||
|
||||
Python build dependencies
|
||||
Some of QEMU's build dependencies are written in Python. Usually these
|
||||
|
@ -32,15 +32,6 @@ import sphinx
|
||||
from distutils.version import LooseVersion
|
||||
from sphinx.errors import ConfigError
|
||||
|
||||
# Make Sphinx fail cleanly if using an old Python, rather than obscurely
|
||||
# failing because some code in one of our extensions doesn't work there.
|
||||
# In newer versions of Sphinx this will display nicely; in older versions
|
||||
# Sphinx will also produce a Python backtrace but at least the information
|
||||
# gets printed...
|
||||
if sys.version_info < (3,6):
|
||||
raise ConfigError(
|
||||
"QEMU requires a Sphinx that uses Python 3.6 or better\n")
|
||||
|
||||
# The per-manual conf.py will set qemu_docdir for a single-manual build;
|
||||
# otherwise set it here if this is an entire-manual-set build.
|
||||
# This is always the absolute path of the docs/ directory in the source tree.
|
||||
|
@ -61,19 +61,19 @@ Under ``tests/avocado/`` as the root we have:
|
||||
::
|
||||
|
||||
$ make check-venv (needed only the first time to create the venv)
|
||||
$ ./tests/venv/bin/avocado run -t acpi tests/avocado
|
||||
$ ./pyvenv/bin/avocado run -t acpi tests/avocado
|
||||
|
||||
The above will run all acpi avocado tests including this one.
|
||||
In order to run the individual tests, perform the following:
|
||||
::
|
||||
|
||||
$ ./tests/venv/bin/avocado run tests/avocado/acpi-bits.py --tap -
|
||||
$ ./pyvenv/bin/avocado run tests/avocado/acpi-bits.py --tap -
|
||||
|
||||
The above will produce output in tap format. You can omit "--tap -" in the
|
||||
end and it will produce output like the following:
|
||||
::
|
||||
|
||||
$ ./tests/venv/bin/avocado run tests/avocado/acpi-bits.py
|
||||
$ ./pyvenv/bin/avocado run tests/avocado/acpi-bits.py
|
||||
Fetching asset from tests/avocado/acpi-bits.py:AcpiBitsTest.test_acpi_smbios_bits
|
||||
JOB ID : eab225724da7b64c012c65705dc2fa14ab1defef
|
||||
JOB LOG : /home/anisinha/avocado/job-results/job-2022-10-10T17.58-eab2257/job.log
|
||||
|
@ -4,30 +4,14 @@ The QEMU build system architecture
|
||||
|
||||
This document aims to help developers understand the architecture of the
|
||||
QEMU build system. As with projects using GNU autotools, the QEMU build
|
||||
system has two stages, first the developer runs the "configure" script
|
||||
system has two stages; first the developer runs the "configure" script
|
||||
to determine the local build environment characteristics, then they run
|
||||
"make" to build the project. There is about where the similarities with
|
||||
"make" to build the project. This is about where the similarities with
|
||||
GNU autotools end, so try to forget what you know about them.
|
||||
|
||||
The two general ways to perform a build are as follows:
|
||||
|
||||
Stage 1: configure
|
||||
==================
|
||||
|
||||
The QEMU configure script is written directly in shell, and should be
|
||||
compatible with any POSIX shell, hence it uses #!/bin/sh. An important
|
||||
implication of this is that it is important to avoid using bash-isms on
|
||||
development platforms where bash is the primary host.
|
||||
|
||||
In contrast to autoconf scripts, QEMU's configure is expected to be
|
||||
silent while it is checking for features. It will only display output
|
||||
when an error occurs, or to show the final feature enablement summary
|
||||
on completion.
|
||||
|
||||
Because QEMU uses the Meson build system under the hood, only VPATH
|
||||
builds are supported. There are two general ways to invoke configure &
|
||||
perform a build:
|
||||
|
||||
- VPATH, build artifacts outside of QEMU source tree entirely::
|
||||
- build artifacts outside of QEMU source tree entirely::
|
||||
|
||||
cd ../
|
||||
mkdir build
|
||||
@ -35,88 +19,122 @@ perform a build:
|
||||
../qemu/configure
|
||||
make
|
||||
|
||||
- VPATH, build artifacts in a subdir of QEMU source tree::
|
||||
- build artifacts in a subdir of QEMU source tree::
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
../configure
|
||||
make
|
||||
|
||||
The configure script automatically recognizes
|
||||
command line options for which a same-named Meson option exists;
|
||||
dashes in the command line are replaced with underscores.
|
||||
Most of the actual build process uses Meson under the hood, therefore
|
||||
build artifacts cannot be placed in the source tree itself.
|
||||
|
||||
Many checks on the compilation environment are still found in configure
|
||||
rather than ``meson.build``, but new checks should be added directly to
|
||||
``meson.build``.
|
||||
|
||||
Patches are also welcome to move existing checks from the configure
|
||||
phase to ``meson.build``. When doing so, ensure that ``meson.build`` does
|
||||
not use anymore the keys that you have removed from ``config-host.mak``.
|
||||
Typically these will be replaced in ``meson.build`` by boolean variables,
|
||||
``get_option('optname')`` invocations, or ``dep.found()`` expressions.
|
||||
In general, the remaining checks have little or no interdependencies,
|
||||
so they can be moved one by one.
|
||||
Stage 1: configure
|
||||
==================
|
||||
|
||||
Helper functions
|
||||
----------------
|
||||
The configure script has five tasks:
|
||||
|
||||
The configure script provides a variety of helper functions to assist
|
||||
developers in checking for system features:
|
||||
- detect the host architecture
|
||||
|
||||
``do_cc $ARGS...``
|
||||
Attempt to run the system C compiler passing it $ARGS...
|
||||
- list the targets for which to build emulators; the list of
|
||||
targets also affects which firmware binaries and tests to build
|
||||
|
||||
``do_cxx $ARGS...``
|
||||
Attempt to run the system C++ compiler passing it $ARGS...
|
||||
- find the compilers (native and cross) used to build executables,
|
||||
firmware and tests. The results are written as either Makefile
|
||||
fragments (``config-host.mak``) or a Meson machine file
|
||||
(``config-meson.cross``)
|
||||
|
||||
``compile_object $CFLAGS``
|
||||
Attempt to compile a test program with the system C compiler using
|
||||
$CFLAGS. The test program must have been previously written to a file
|
||||
called $TMPC. The replacement in Meson is the compiler object ``cc``,
|
||||
which has methods such as ``cc.compiles()``,
|
||||
``cc.check_header()``, ``cc.has_function()``.
|
||||
- create a virtual environment in which all Python code runs during
|
||||
the build, and possibly install packages into it from PyPI
|
||||
|
||||
``compile_prog $CFLAGS $LDFLAGS``
|
||||
Attempt to compile a test program with the system C compiler using
|
||||
$CFLAGS and link it with the system linker using $LDFLAGS. The test
|
||||
program must have been previously written to a file called $TMPC.
|
||||
The replacement in Meson is ``cc.find_library()`` and ``cc.links()``.
|
||||
- invoke Meson in the virtual environment, to perform the actual
|
||||
configuration step for the emulator build
|
||||
|
||||
The configure script automatically recognizes command line options for
|
||||
which a same-named Meson option exists; dashes in the command line are
|
||||
replaced with underscores.
|
||||
|
||||
Almost all QEMU developers that need to modify the build system will
|
||||
only be concerned with Meson, and therefore can skip the rest of this
|
||||
section.
|
||||
|
||||
|
||||
Modifying ``configure``
|
||||
-----------------------
|
||||
|
||||
``configure`` is a shell script; it uses ``#!/bin/sh`` and therefore
|
||||
should be compatible with any POSIX shell. It is important to avoid
|
||||
using bash-isms to avoid breaking development platforms where bash is
|
||||
the primary host.
|
||||
|
||||
The configure script provides a variety of functions to help writing
|
||||
portable shell code and providing consistent behavior across architectures
|
||||
and operating systems:
|
||||
|
||||
``error_exit $MESSAGE $MORE...``
|
||||
Print $MESSAGE to stderr, followed by $MORE... and then exit from the
|
||||
configure script with non-zero status.
|
||||
|
||||
``has $COMMAND``
|
||||
Determine if $COMMAND exists in the current environment, either as a
|
||||
shell builtin, or executable binary, returning 0 on success. The
|
||||
replacement in Meson is ``find_program()``.
|
||||
|
||||
``check_define $NAME``
|
||||
Determine if the macro $NAME is defined by the system C compiler
|
||||
``probe_target_compiler $TARGET``
|
||||
Detect a cross compiler and cross tools for the QEMU target $TARGET (e.g.,
|
||||
``$CPU-softmmu``, ``$CPU-linux-user``, ``$CPU-bsd-user``). If a working
|
||||
compiler is present, return success and set variables ``$target_cc``,
|
||||
``$target_ar``, etc. to non-empty values.
|
||||
|
||||
``check_include $NAME``
|
||||
Determine if the include $NAME file is available to the system C
|
||||
compiler. The replacement in Meson is ``cc.has_header()``.
|
||||
``write_target_makefile``
|
||||
Write a Makefile fragment to stdout, exposing the result of the most
|
||||
``probe_target_compiler`` call as the usual Make variables (``CC``,
|
||||
``AR``, ``LD``, etc.).
|
||||
|
||||
|
||||
Configure does not generally perform tests for compiler options beyond
|
||||
basic checks to detect the host platform and ensure the compiler is
|
||||
functioning. These are performed using a few more helper functions:
|
||||
|
||||
``compile_object $CFLAGS``
|
||||
Attempt to compile a test program with the system C compiler using
|
||||
$CFLAGS. The test program must have been previously written to a file
|
||||
called $TMPC.
|
||||
|
||||
``compile_prog $CFLAGS $LDFLAGS``
|
||||
Attempt to compile a test program with the system C compiler using
|
||||
$CFLAGS and link it with the system linker using $LDFLAGS. The test
|
||||
program must have been previously written to a file called $TMPC.
|
||||
|
||||
``check_define $NAME``
|
||||
Determine if the macro $NAME is defined by the system C compiler.
|
||||
|
||||
``do_compiler $CC $ARGS...``
|
||||
Attempt to run the C compiler $CC, passing it $ARGS... This function
|
||||
does not use flags passed via options such as ``--extra-cflags``, and
|
||||
therefore can be used to check for cross compilers. However, most
|
||||
such checks are done at ``make`` time instead (see for example the
|
||||
``cc-option`` macro in ``pc-bios/option-rom/Makefile``).
|
||||
|
||||
``write_c_skeleton``
|
||||
Write a minimal C program main() function to the temporary file
|
||||
indicated by $TMPC
|
||||
indicated by $TMPC.
|
||||
|
||||
``error_exit $MESSAGE $MORE...``
|
||||
Print $MESSAGE to stderr, followed by $MORE... and then exit from the
|
||||
configure script with non-zero status
|
||||
|
||||
``query_pkg_config $ARGS...``
|
||||
Run pkg-config passing it $ARGS. If QEMU is doing a static build,
|
||||
then --static will be automatically added to $ARGS
|
||||
Python virtual environments and the QEMU build system
|
||||
-----------------------------------------------------
|
||||
|
||||
TBD
|
||||
|
||||
Stage 2: Meson
|
||||
==============
|
||||
|
||||
The Meson build system is currently used to describe the build
|
||||
process for:
|
||||
The Meson build system describes the build and install process for:
|
||||
|
||||
1) executables, which include:
|
||||
|
||||
- Tools - ``qemu-img``, ``qemu-nbd``, ``qga`` (guest agent), etc
|
||||
- Tools - ``qemu-img``, ``qemu-nbd``, ``qemu-ga`` (guest agent), etc
|
||||
|
||||
- System emulators - ``qemu-system-$ARCH``
|
||||
|
||||
@ -126,7 +144,8 @@ process for:
|
||||
|
||||
2) documentation
|
||||
|
||||
3) ROMs, which can be either installed as binary blobs or compiled
|
||||
3) ROMs, whether provided as binary blobs in the QEMU distributions
|
||||
or cross compiled under the direction of the configure script
|
||||
|
||||
4) other data files, such as icons or desktop files
|
||||
|
||||
@ -281,8 +300,7 @@ system/userspace emulation target
|
||||
Adding checks
|
||||
-------------
|
||||
|
||||
New checks should be added to Meson. Compiler checks can be as simple as
|
||||
the following::
|
||||
Compiler checks can be as simple as the following::
|
||||
|
||||
config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
|
||||
|
||||
@ -311,8 +329,7 @@ dependency will be used::
|
||||
sdl_image = not_found
|
||||
if not get_option('sdl_image').auto() or have_system
|
||||
sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
|
||||
method: 'pkg-config',
|
||||
static: enable_static)
|
||||
method: 'pkg-config')
|
||||
endif
|
||||
|
||||
This avoids warnings on static builds of user-mode emulators, for example.
|
||||
@ -360,22 +377,30 @@ script, which may point to something other than the first python3
|
||||
binary on the path.
|
||||
|
||||
|
||||
Stage 3: makefiles
|
||||
==================
|
||||
Stage 3: Make
|
||||
=============
|
||||
|
||||
The use of GNU make is required with the QEMU build system.
|
||||
The next step in building QEMU is to invoke make. GNU Make is required
|
||||
to build QEMU, and may be installed as ``gmake`` on some hosts.
|
||||
|
||||
The output of Meson is a build.ninja file, which is used with the Ninja
|
||||
build system. QEMU uses a different approach, where Makefile rules are
|
||||
synthesized from the build.ninja file. The main Makefile includes these
|
||||
rules and wraps them so that e.g. submodules are built before QEMU.
|
||||
The resulting build system is largely non-recursive in nature, in
|
||||
contrast to common practices seen with automake.
|
||||
The output of Meson is a ``build.ninja`` file, which is used with the
|
||||
Ninja build tool. However, QEMU's build comprises other components than
|
||||
just the emulators (namely firmware and the tests in ``tests/tcg``) which
|
||||
need different cross compilers. The QEMU Makefile wraps both Ninja and
|
||||
the smaller build systems for firmware and tests; it also takes care of
|
||||
running ``configure`` again when the script changes. Apart from invoking
|
||||
these sub-Makefiles, the resulting build is largely non-recursive.
|
||||
|
||||
Tests are also ran by the Makefile with the traditional ``make check``
|
||||
phony target, while benchmarks are run with ``make bench``. Meson test
|
||||
suites such as ``unit`` can be ran with ``make check-unit`` too. It is also
|
||||
possible to run tests defined in meson.build with ``meson test``.
|
||||
Tests, whether defined in ``meson.build`` or not, are also ran by the
|
||||
Makefile with the traditional ``make check`` phony target, while benchmarks
|
||||
are run with ``make bench``. Meson test suites such as ``unit`` can be ran
|
||||
with ``make check-unit``, and ``make check-tcg`` builds and runs "non-Meson"
|
||||
tests for all targets.
|
||||
|
||||
If desired, it is also possible to use ``ninja`` and ``meson test``,
|
||||
respectively to build emulators and run tests defined in meson.build.
|
||||
The main difference is that ``make`` needs the ``-jN`` flag in order to
|
||||
enable parallel builds or tests.
|
||||
|
||||
Useful make targets
|
||||
-------------------
|
||||
@ -387,6 +412,7 @@ Useful make targets
|
||||
Print the value of the variable VAR. Useful for debugging the build
|
||||
system.
|
||||
|
||||
|
||||
Important files for the build system
|
||||
====================================
|
||||
|
||||
@ -400,8 +426,7 @@ number of dynamically created files listed later.
|
||||
``Makefile``
|
||||
The main entry point used when invoking make to build all the components
|
||||
of QEMU. The default 'all' target will naturally result in the build of
|
||||
every component. Makefile takes care of recursively building submodules
|
||||
directly via a non-recursive set of rules.
|
||||
every component.
|
||||
|
||||
``*/meson.build``
|
||||
The meson.build file in the root directory is the main entry point for the
|
||||
@ -410,59 +435,92 @@ number of dynamically created files listed later.
|
||||
other meson.build files spread throughout the QEMU source tree.
|
||||
|
||||
``tests/Makefile.include``
|
||||
Rules for external test harnesses. These include the TCG tests,
|
||||
``qemu-iotests`` and the Avocado-based integration tests.
|
||||
Rules for external test harnesses. These include the TCG tests
|
||||
and the Avocado-based integration tests.
|
||||
|
||||
``tests/docker/Makefile.include``
|
||||
Rules for Docker tests. Like tests/Makefile, this file is included
|
||||
directly by the top level Makefile, anything defined in this file will
|
||||
influence the entire build system.
|
||||
Rules for Docker tests. Like ``tests/Makefile.include``, this file is
|
||||
included directly by the top level Makefile, anything defined in this
|
||||
file will influence the entire build system.
|
||||
|
||||
``tests/vm/Makefile.include``
|
||||
Rules for VM-based tests. Like tests/Makefile, this file is included
|
||||
directly by the top level Makefile, anything defined in this file will
|
||||
influence the entire build system.
|
||||
Rules for VM-based tests. Like ``tests/Makefile.include``, this file is
|
||||
included directly by the top level Makefile, anything defined in this
|
||||
file will influence the entire build system.
|
||||
|
||||
Dynamically created files
|
||||
-------------------------
|
||||
|
||||
The following files are generated dynamically by configure in order to
|
||||
control the behaviour of the statically defined makefiles. This avoids
|
||||
the need for QEMU makefiles to go through any pre-processing as seen
|
||||
with autotools, where Makefile.am generates Makefile.in which generates
|
||||
Makefile.
|
||||
The following files are generated at run-time in order to control the
|
||||
behaviour of the Makefiles. This avoids the need for QEMU makefiles to
|
||||
go through any pre-processing as seen with autotools, where configure
|
||||
generates ``Makefile`` from ``Makefile.in``.
|
||||
|
||||
Built by configure:
|
||||
|
||||
``config-host.mak``
|
||||
When configure has determined the characteristics of the build host it
|
||||
will write a long list of variables to config-host.mak file. This
|
||||
provides the various install directories, compiler / linker flags and a
|
||||
will write them to this file for use in ``Makefile`` and to a smaller
|
||||
extent ``meson.build``. These include the paths to various tools and a
|
||||
variety of ``CONFIG_*`` variables related to optionally enabled features.
|
||||
This is imported by the top level Makefile and meson.build in order to
|
||||
tailor the build output.
|
||||
|
||||
config-host.mak is also used as a dependency checking mechanism. If make
|
||||
``config-host.mak`` is also used as a dependency checking mechanism. If make
|
||||
sees that the modification timestamp on configure is newer than that on
|
||||
config-host.mak, then configure will be re-run.
|
||||
``config-host.mak``, then configure will be re-run.
|
||||
|
||||
The variables defined here are those which are applicable to all QEMU
|
||||
build outputs. Variables which are potentially different for each
|
||||
emulator target are defined by the next file...
|
||||
The variables defined here apply to all QEMU
|
||||
build outputs.
|
||||
|
||||
``config-meson.cross``
|
||||
|
||||
A Meson "cross file" (or native file) used to communicate the paths to
|
||||
the toolchain and other configuration options.
|
||||
|
||||
``config.status``
|
||||
|
||||
A small shell script that will invoke configure again with the same
|
||||
environment variables that were set during the first run. It's used to
|
||||
rerun configure after changes to the source code, but it can also be
|
||||
inspected manually to check the contents of the environment.
|
||||
|
||||
``Makefile.prereqs``
|
||||
|
||||
A set of Makefile dependencies that order the build and execution of
|
||||
firmware and tests after the container images and emulators that they
|
||||
need.
|
||||
|
||||
``pc-bios/*/config.mak``, ``tests/tcg/config-host.mak``, ``tests/tcg/*/config-target.mak``
|
||||
|
||||
Configuration variables used to build the firmware and TCG tests,
|
||||
including paths to cross compilation toolchains.
|
||||
|
||||
``pyvenv``
|
||||
|
||||
A Python virtual environment that is used for all Python code running
|
||||
during the build. Using a virtual environment ensures that even code
|
||||
that is run via ``sphinx-build``, ``meson`` etc. uses the same interpreter
|
||||
and packages.
|
||||
|
||||
Built by Meson:
|
||||
|
||||
``${TARGET-NAME}-config-devices.mak``
|
||||
TARGET-NAME is again the name of a system or userspace emulator. The
|
||||
config-devices.mak file is automatically generated by make using the
|
||||
scripts/make_device_config.sh program, feeding it the
|
||||
default-configs/$TARGET-NAME file as input.
|
||||
``config-host.h``
|
||||
Used by C code to determine the properties of the build environment
|
||||
and the set of enabled features for the entire build.
|
||||
|
||||
``config-host.h``, ``$TARGET_NAME-config-target.h``, ``$TARGET_NAME-config-devices.h``
|
||||
These files are used by source code to determine what features are
|
||||
enabled. They are generated from the contents of the corresponding
|
||||
``*.mak`` files using Meson's ``configure_file()`` function.
|
||||
``${TARGET-NAME}-config-devices.mak``
|
||||
TARGET-NAME is the name of a system emulator. The file is
|
||||
generated by Meson using files under ``configs/devices`` as input.
|
||||
|
||||
``${TARGET-NAME}-config-target.mak``
|
||||
TARGET-NAME is the name of a system or usermode emulator. The file is
|
||||
generated by Meson using files under ``configs/targets`` as input.
|
||||
|
||||
``$TARGET_NAME-config-target.h``, ``$TARGET_NAME-config-devices.h``
|
||||
Used by C code to determine the properties and enabled
|
||||
features for each target. enabled. They are generated from
|
||||
the contents of the corresponding ``*.mak`` files using Meson's
|
||||
``configure_file()`` function; each target can include them using
|
||||
the ``CONFIG_TARGET`` and ``CONFIG_DEVICES`` macro respectively.
|
||||
|
||||
``build.ninja``
|
||||
The build rules.
|
||||
|
@ -888,9 +888,9 @@ You can run the avocado tests simply by executing:
|
||||
|
||||
make check-avocado
|
||||
|
||||
This involves the automatic creation of Python virtual environment
|
||||
within the build tree (at ``tests/venv``) which will have all the
|
||||
right dependencies, and will save tests results also within the
|
||||
This involves the automatic installation, from PyPI, of all the
|
||||
necessary avocado-framework dependencies into the QEMU venv within the
|
||||
build tree (at ``./pyvenv``). Test results are also saved within the
|
||||
build tree (at ``tests/results``).
|
||||
|
||||
Note: the build environment must be using a Python 3 stack, and have
|
||||
@ -947,7 +947,7 @@ may be invoked by running:
|
||||
|
||||
.. code::
|
||||
|
||||
tests/venv/bin/avocado run $OPTION1 $OPTION2 tests/avocado/
|
||||
pyvenv/bin/avocado run $OPTION1 $OPTION2 tests/avocado/
|
||||
|
||||
Note that if ``make check-avocado`` was not executed before, it is
|
||||
possible to create the Python virtual environment with the dependencies
|
||||
@ -962,20 +962,20 @@ a test file. To run tests from a single file within the build tree, use:
|
||||
|
||||
.. code::
|
||||
|
||||
tests/venv/bin/avocado run tests/avocado/$TESTFILE
|
||||
pyvenv/bin/avocado run tests/avocado/$TESTFILE
|
||||
|
||||
To run a single test within a test file, use:
|
||||
|
||||
.. code::
|
||||
|
||||
tests/venv/bin/avocado run tests/avocado/$TESTFILE:$TESTCLASS.$TESTNAME
|
||||
pyvenv/bin/avocado run tests/avocado/$TESTFILE:$TESTCLASS.$TESTNAME
|
||||
|
||||
Valid test names are visible in the output from any previous execution
|
||||
of Avocado or ``make check-avocado``, and can also be queried using:
|
||||
|
||||
.. code::
|
||||
|
||||
tests/venv/bin/avocado list tests/avocado
|
||||
pyvenv/bin/avocado list tests/avocado
|
||||
|
||||
Manual Installation
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -1,4 +1,4 @@
|
||||
sphinx_build = find_program(get_option('sphinx_build'),
|
||||
sphinx_build = find_program(fs.parent(python.full_path()) / 'sphinx-build',
|
||||
required: get_option('docs'))
|
||||
|
||||
# Check if tools are available to build documentation.
|
||||
@ -10,6 +10,18 @@ if sphinx_build.found()
|
||||
SPHINX_ARGS += [ '-W', '-Dkerneldoc_werror=1' ]
|
||||
endif
|
||||
|
||||
sphinx_version = run_command(SPHINX_ARGS + ['--version'],
|
||||
check: true).stdout().split()[1]
|
||||
if sphinx_version.version_compare('>=1.7.0')
|
||||
SPHINX_ARGS += ['-j', 'auto']
|
||||
else
|
||||
nproc = find_program('nproc')
|
||||
if nproc.found()
|
||||
jobs = run_command(nproc, check: true).stdout()
|
||||
SPHINX_ARGS += ['-j', jobs]
|
||||
endif
|
||||
endif
|
||||
|
||||
# This is a bit awkward but works: create a trivial document and
|
||||
# try to run it with our configuration file (which enforces a
|
||||
# version requirement). This will fail if sphinx-build is too old.
|
||||
|
@ -400,6 +400,10 @@ class DBusDomain(Domain):
|
||||
for refname, obj in self.objects.items():
|
||||
yield (refname, refname, obj.objtype, obj.docname, obj.node_id, 1)
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
for name, obj in otherdata['objects'].items():
|
||||
if obj.docname in docnames:
|
||||
self.data['objects'][name] = obj
|
||||
|
||||
def setup(app):
|
||||
app.add_domain(DBusDomain)
|
||||
|
@ -23,3 +23,8 @@ class FakeDBusDocDirective(Directive):
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
"""Register a fake dbus-doc directive with Sphinx"""
|
||||
app.add_directive("dbus-doc", FakeDBusDocDirective)
|
||||
|
||||
return dict(
|
||||
parallel_read_safe = True,
|
||||
parallel_write_safe = True
|
||||
)
|
||||
|
@ -41,3 +41,8 @@ def setup(sphinx):
|
||||
sphinx.add_lexer('QMP', QMPExampleLexer)
|
||||
except errors.VersionRequirementError:
|
||||
sphinx.add_lexer('QMP', QMPExampleLexer())
|
||||
|
||||
return dict(
|
||||
parallel_read_safe = True,
|
||||
parallel_write_safe = True
|
||||
)
|
||||
|
@ -191,12 +191,16 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
|
||||
if ((s->type == TYPE_DISK || s->type == TYPE_ZBC) &&
|
||||
(r->req.cmd.buf[1] & 0x01)) {
|
||||
page = r->req.cmd.buf[2];
|
||||
if (page == 0xb0) {
|
||||
if (page == 0xb0 && r->buflen >= 8) {
|
||||
uint8_t buf[16] = {};
|
||||
uint8_t buf_used = MIN(r->buflen, 16);
|
||||
uint64_t max_transfer = calculate_max_transfer(s);
|
||||
stl_be_p(&r->buf[8], max_transfer);
|
||||
/* Also take care of the opt xfer len. */
|
||||
stl_be_p(&r->buf[12],
|
||||
MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
|
||||
|
||||
memcpy(buf, r->buf, buf_used);
|
||||
stl_be_p(&buf[8], max_transfer);
|
||||
stl_be_p(&buf[12], MIN_NON_ZERO(max_transfer, ldl_be_p(&buf[12])));
|
||||
memcpy(r->buf + 8, buf + 8, buf_used - 8);
|
||||
|
||||
} else if (s->needs_vpd_bl_emulation && page == 0x00 && r->buflen >= 4) {
|
||||
/*
|
||||
* Now we're capable of supplying the VPD Block Limits
|
||||
|
@ -934,8 +934,11 @@ struct MemoryListener {
|
||||
* its @log_sync must be NULL. Vice versa.
|
||||
*
|
||||
* @listener: The #MemoryListener.
|
||||
* @last_stage: The last stage to synchronize the log during migration.
|
||||
* The caller should gurantee that the synchronization with true for
|
||||
* @last_stage is triggered for once after all VCPUs have been stopped.
|
||||
*/
|
||||
void (*log_sync_global)(MemoryListener *listener);
|
||||
void (*log_sync_global)(MemoryListener *listener, bool last_stage);
|
||||
|
||||
/**
|
||||
* @log_clear:
|
||||
@ -2422,8 +2425,10 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
|
||||
* memory_global_dirty_log_sync: synchronize the dirty log for all memory
|
||||
*
|
||||
* Synchronizes the dirty page log for all address spaces.
|
||||
*
|
||||
* @last_stage: whether this is the last stage of live migration
|
||||
*/
|
||||
void memory_global_dirty_log_sync(void);
|
||||
void memory_global_dirty_log_sync(bool last_stage);
|
||||
|
||||
/**
|
||||
* memory_global_dirty_log_sync: synchronize the dirty log for all memory
|
||||
|
@ -115,6 +115,7 @@ struct KVMState
|
||||
} *as;
|
||||
uint64_t kvm_dirty_ring_bytes; /* Size of the per-vcpu dirty ring */
|
||||
uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */
|
||||
bool kvm_dirty_ring_with_bitmap;
|
||||
struct KVMDirtyRingReaper reaper;
|
||||
NotifyVmexitOption notify_vmexit;
|
||||
uint32_t notify_window;
|
||||
|
1
meson
1
meson
@ -1 +0,0 @@
|
||||
Subproject commit 3a9b285a55b91b53b2acda987192274352ecb5be
|
661
meson.build
661
meson.build
File diff suppressed because it is too large
Load Diff
@ -12,8 +12,6 @@ option('pkgversion', type : 'string', value : '',
|
||||
description: 'use specified string as sub-version of the package')
|
||||
option('smbd', type : 'string', value : '',
|
||||
description: 'Path to smbd for slirp networking')
|
||||
option('sphinx_build', type : 'string', value : 'sphinx-build',
|
||||
description: 'Use specified sphinx-build for building document')
|
||||
option('iasl', type : 'string', value : '',
|
||||
description: 'Path to ACPI disassembler')
|
||||
option('tls_priority', type : 'string', value : 'NORMAL',
|
||||
@ -33,6 +31,9 @@ option('fuzzing_engine', type : 'string', value : '',
|
||||
description: 'fuzzing engine library for OSS-Fuzz')
|
||||
option('trace_file', type: 'string', value: 'trace',
|
||||
description: 'Trace file prefix for simple backend')
|
||||
option('coroutine_backend', type: 'combo',
|
||||
choices: ['ucontext', 'sigaltstack', 'windows', 'auto'],
|
||||
value: 'auto', description: 'coroutine backend to use')
|
||||
|
||||
# Everything else can be set via --enable/--disable-* option
|
||||
# on the configure script command line. After adding an option
|
||||
@ -44,6 +45,8 @@ option('fuzzing', type : 'boolean', value: false,
|
||||
description: 'build fuzzing targets')
|
||||
option('gettext', type : 'feature', value : 'auto',
|
||||
description: 'Localization of the GTK+ user interface')
|
||||
option('modules', type : 'feature', value : 'disabled',
|
||||
description: 'modules support (non Windows)')
|
||||
option('module_upgrades', type : 'boolean', value : false,
|
||||
description: 'try to load modules from alternate paths for upgrades')
|
||||
option('install_blobs', type : 'boolean', value : true,
|
||||
@ -82,6 +85,14 @@ option('tcg', type: 'feature', value: 'enabled',
|
||||
description: 'TCG support')
|
||||
option('tcg_interpreter', type: 'boolean', value: false,
|
||||
description: 'TCG with bytecode interpreter (slow)')
|
||||
option('safe_stack', type: 'boolean', value: false,
|
||||
description: 'SafeStack Stack Smash Protection (requires clang/llvm and coroutine backend ucontext)')
|
||||
option('sanitizers', type: 'boolean', value: false,
|
||||
description: 'enable default sanitizers')
|
||||
option('tsan', type: 'boolean', value: false,
|
||||
description: 'enable thread sanitizer')
|
||||
option('stack_protector', type: 'feature', value: 'auto',
|
||||
description: 'compiler-provided stack protection')
|
||||
option('cfi', type: 'boolean', value: false,
|
||||
description: 'Control-Flow Integrity (CFI)')
|
||||
option('cfi_debug', type: 'boolean', value: false,
|
||||
|
@ -101,7 +101,7 @@ void global_dirty_log_change(unsigned int flag, bool start)
|
||||
static void global_dirty_log_sync(unsigned int flag, bool one_shot)
|
||||
{
|
||||
qemu_mutex_lock_iothread();
|
||||
memory_global_dirty_log_sync();
|
||||
memory_global_dirty_log_sync(false);
|
||||
if (one_shot) {
|
||||
memory_global_dirty_log_stop(flag);
|
||||
}
|
||||
@ -581,7 +581,7 @@ static void calculate_dirtyrate_dirty_bitmap(struct DirtyRateConfig config)
|
||||
* skip it unconditionally and start dirty tracking
|
||||
* from 2'round of log sync
|
||||
*/
|
||||
memory_global_dirty_log_sync();
|
||||
memory_global_dirty_log_sync(false);
|
||||
|
||||
/*
|
||||
* reset page protect manually and unconditionally.
|
||||
|
@ -1039,7 +1039,7 @@ static void migration_trigger_throttle(RAMState *rs)
|
||||
}
|
||||
}
|
||||
|
||||
static void migration_bitmap_sync(RAMState *rs)
|
||||
static void migration_bitmap_sync(RAMState *rs, bool last_stage)
|
||||
{
|
||||
RAMBlock *block;
|
||||
int64_t end_time;
|
||||
@ -1051,7 +1051,7 @@ static void migration_bitmap_sync(RAMState *rs)
|
||||
}
|
||||
|
||||
trace_migration_bitmap_sync_start();
|
||||
memory_global_dirty_log_sync();
|
||||
memory_global_dirty_log_sync(last_stage);
|
||||
|
||||
qemu_mutex_lock(&rs->bitmap_mutex);
|
||||
WITH_RCU_READ_LOCK_GUARD() {
|
||||
@ -1086,7 +1086,7 @@ static void migration_bitmap_sync(RAMState *rs)
|
||||
}
|
||||
}
|
||||
|
||||
static void migration_bitmap_sync_precopy(RAMState *rs)
|
||||
static void migration_bitmap_sync_precopy(RAMState *rs, bool last_stage)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
|
||||
@ -1099,7 +1099,7 @@ static void migration_bitmap_sync_precopy(RAMState *rs)
|
||||
local_err = NULL;
|
||||
}
|
||||
|
||||
migration_bitmap_sync(rs);
|
||||
migration_bitmap_sync(rs, last_stage);
|
||||
|
||||
if (precopy_notify(PRECOPY_NOTIFY_AFTER_BITMAP_SYNC, &local_err)) {
|
||||
error_report_err(local_err);
|
||||
@ -2699,7 +2699,7 @@ void ram_postcopy_send_discard_bitmap(MigrationState *ms)
|
||||
RCU_READ_LOCK_GUARD();
|
||||
|
||||
/* This should be our last sync, the src is now paused */
|
||||
migration_bitmap_sync(rs);
|
||||
migration_bitmap_sync(rs, false);
|
||||
|
||||
/* Easiest way to make sure we don't resume in the middle of a host-page */
|
||||
rs->pss[RAM_CHANNEL_PRECOPY].last_sent_block = NULL;
|
||||
@ -2890,7 +2890,7 @@ static void ram_init_bitmaps(RAMState *rs)
|
||||
/* We don't use dirty log with background snapshots */
|
||||
if (!migrate_background_snapshot()) {
|
||||
memory_global_dirty_log_start(GLOBAL_DIRTY_MIGRATION);
|
||||
migration_bitmap_sync_precopy(rs);
|
||||
migration_bitmap_sync_precopy(rs, false);
|
||||
}
|
||||
}
|
||||
qemu_mutex_unlock_ramlist();
|
||||
@ -3214,7 +3214,7 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
|
||||
|
||||
WITH_RCU_READ_LOCK_GUARD() {
|
||||
if (!migration_in_postcopy()) {
|
||||
migration_bitmap_sync_precopy(rs);
|
||||
migration_bitmap_sync_precopy(rs, true);
|
||||
}
|
||||
|
||||
ram_control_before_iterate(f, RAM_CONTROL_FINISH);
|
||||
@ -3288,7 +3288,7 @@ static void ram_state_pending_exact(void *opaque, uint64_t *must_precopy,
|
||||
if (!migration_in_postcopy() && remaining_size < s->threshold_size) {
|
||||
qemu_mutex_lock_iothread();
|
||||
WITH_RCU_READ_LOCK_GUARD() {
|
||||
migration_bitmap_sync_precopy(rs);
|
||||
migration_bitmap_sync_precopy(rs, false);
|
||||
}
|
||||
qemu_mutex_unlock_iothread();
|
||||
remaining_size = rs->migration_dirty_pages * TARGET_PAGE_SIZE;
|
||||
@ -3523,7 +3523,7 @@ void colo_incoming_start_dirty_log(void)
|
||||
qemu_mutex_lock_iothread();
|
||||
qemu_mutex_lock_ramlist();
|
||||
|
||||
memory_global_dirty_log_sync();
|
||||
memory_global_dirty_log_sync(false);
|
||||
WITH_RCU_READ_LOCK_GUARD() {
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
|
||||
ramblock_sync_dirty_bitmap(ram_state, block);
|
||||
@ -3813,7 +3813,7 @@ void colo_flush_ram_cache(void)
|
||||
void *src_host;
|
||||
unsigned long offset = 0;
|
||||
|
||||
memory_global_dirty_log_sync();
|
||||
memory_global_dirty_log_sync(false);
|
||||
qemu_mutex_lock(&ram_state->bitmap_mutex);
|
||||
WITH_RCU_READ_LOCK_GUARD() {
|
||||
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
|
||||
|
@ -9,14 +9,14 @@ help:
|
||||
@echo "make check-minreqs:"
|
||||
@echo " Run tests in the minreqs virtual environment."
|
||||
@echo " These tests use the oldest dependencies."
|
||||
@echo " Requires: Python 3.6"
|
||||
@echo " Hint (Fedora): 'sudo dnf install python3.6'"
|
||||
@echo " Requires: Python 3.7"
|
||||
@echo " Hint (Fedora): 'sudo dnf install python3.7'"
|
||||
@echo ""
|
||||
@echo "make check-tox:"
|
||||
@echo " Run tests against multiple python versions."
|
||||
@echo " These tests use the newest dependencies."
|
||||
@echo " Requires: Python 3.6 - 3.10, and tox."
|
||||
@echo " Hint (Fedora): 'sudo dnf install python3-tox python3.10'"
|
||||
@echo " Requires: Python 3.7 - 3.11, and tox."
|
||||
@echo " Hint (Fedora): 'sudo dnf install python3-tox python3.11'"
|
||||
@echo " The variable QEMU_TOX_EXTRA_ARGS can be use to pass extra"
|
||||
@echo " arguments to tox".
|
||||
@echo ""
|
||||
@ -54,18 +54,21 @@ pipenv check-pipenv:
|
||||
@echo "pipenv was dropped; try 'make check-minreqs' or 'make min-venv'"
|
||||
@exit 1
|
||||
|
||||
PIP_INSTALL = pip install --disable-pip-version-check
|
||||
.PHONY: min-venv
|
||||
min-venv: $(QEMU_MINVENV_DIR) $(QEMU_MINVENV_DIR)/bin/activate
|
||||
$(QEMU_MINVENV_DIR) $(QEMU_MINVENV_DIR)/bin/activate: setup.cfg tests/minreqs.txt
|
||||
@echo "VENV $(QEMU_MINVENV_DIR)"
|
||||
@python3.6 -m venv $(QEMU_MINVENV_DIR)
|
||||
@python3.7 -m venv $(QEMU_MINVENV_DIR)
|
||||
@( \
|
||||
echo "ACTIVATE $(QEMU_MINVENV_DIR)"; \
|
||||
. $(QEMU_MINVENV_DIR)/bin/activate; \
|
||||
echo "INSTALL wheel $(QEMU_MINVENV_DIR)"; \
|
||||
$(PIP_INSTALL) wheel 1>/dev/null; \
|
||||
echo "INSTALL -r tests/minreqs.txt $(QEMU_MINVENV_DIR)";\
|
||||
pip install -r tests/minreqs.txt 1>/dev/null; \
|
||||
$(PIP_INSTALL) -r tests/minreqs.txt 1>/dev/null; \
|
||||
echo "INSTALL -e qemu $(QEMU_MINVENV_DIR)"; \
|
||||
pip install -e . 1>/dev/null; \
|
||||
$(PIP_INSTALL) -e . 1>/dev/null; \
|
||||
)
|
||||
@touch $(QEMU_MINVENV_DIR)
|
||||
|
||||
@ -100,7 +103,7 @@ check-dev: dev-venv
|
||||
|
||||
.PHONY: develop
|
||||
develop:
|
||||
pip3 install --disable-pip-version-check -e .[devel]
|
||||
$(PIP_INSTALL) -e .[devel]
|
||||
|
||||
.PHONY: check
|
||||
check:
|
||||
|
897
python/scripts/mkvenv.py
Normal file
897
python/scripts/mkvenv.py
Normal file
@ -0,0 +1,897 @@
|
||||
"""
|
||||
mkvenv - QEMU pyvenv bootstrapping utility
|
||||
|
||||
usage: mkvenv [-h] command ...
|
||||
|
||||
QEMU pyvenv bootstrapping utility
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
|
||||
Commands:
|
||||
command Description
|
||||
create create a venv
|
||||
post_init
|
||||
post-venv initialization
|
||||
ensure Ensure that the specified package is installed.
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
usage: mkvenv create [-h] target
|
||||
|
||||
positional arguments:
|
||||
target Target directory to install virtual environment into.
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
usage: mkvenv post_init [-h]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
usage: mkvenv ensure [-h] [--online] [--dir DIR] dep_spec...
|
||||
|
||||
positional arguments:
|
||||
dep_spec PEP 508 Dependency specification, e.g. 'meson>=0.61.5'
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--online Install packages from PyPI, if necessary.
|
||||
--dir DIR Path to vendored packages where we may install from.
|
||||
|
||||
"""
|
||||
|
||||
# Copyright (C) 2022-2023 Red Hat, Inc.
|
||||
#
|
||||
# Authors:
|
||||
# John Snow <jsnow@redhat.com>
|
||||
# Paolo Bonzini <pbonzini@redhat.com>
|
||||
#
|
||||
# This work is licensed under the terms of the GNU GPL, version 2 or
|
||||
# later. See the COPYING file in the top-level directory.
|
||||
|
||||
import argparse
|
||||
from importlib.util import find_spec
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import shutil
|
||||
import site
|
||||
import subprocess
|
||||
import sys
|
||||
import sysconfig
|
||||
from types import SimpleNamespace
|
||||
from typing import (
|
||||
Any,
|
||||
Iterator,
|
||||
Optional,
|
||||
Sequence,
|
||||
Tuple,
|
||||
Union,
|
||||
)
|
||||
import venv
|
||||
import warnings
|
||||
|
||||
|
||||
# Try to load distlib, with a fallback to pip's vendored version.
|
||||
# HAVE_DISTLIB is checked below, just-in-time, so that mkvenv does not fail
|
||||
# outside the venv or before a potential call to ensurepip in checkpip().
|
||||
HAVE_DISTLIB = True
|
||||
try:
|
||||
import distlib.database
|
||||
import distlib.scripts
|
||||
import distlib.version
|
||||
except ImportError:
|
||||
try:
|
||||
# Reach into pip's cookie jar. pylint and flake8 don't understand
|
||||
# that these imports will be used via distlib.xxx.
|
||||
from pip._vendor import distlib
|
||||
import pip._vendor.distlib.database # noqa, pylint: disable=unused-import
|
||||
import pip._vendor.distlib.scripts # noqa, pylint: disable=unused-import
|
||||
import pip._vendor.distlib.version # noqa, pylint: disable=unused-import
|
||||
except ImportError:
|
||||
HAVE_DISTLIB = False
|
||||
|
||||
# Do not add any mandatory dependencies from outside the stdlib:
|
||||
# This script *must* be usable standalone!
|
||||
|
||||
DirType = Union[str, bytes, "os.PathLike[str]", "os.PathLike[bytes]"]
|
||||
logger = logging.getLogger("mkvenv")
|
||||
|
||||
|
||||
def inside_a_venv() -> bool:
|
||||
"""Returns True if it is executed inside of a virtual environment."""
|
||||
return sys.prefix != sys.base_prefix
|
||||
|
||||
|
||||
class Ouch(RuntimeError):
|
||||
"""An Exception class we can't confuse with a builtin."""
|
||||
|
||||
|
||||
class QemuEnvBuilder(venv.EnvBuilder):
|
||||
"""
|
||||
An extension of venv.EnvBuilder for building QEMU's configure-time venv.
|
||||
|
||||
The primary difference is that it emulates a "nested" virtual
|
||||
environment when invoked from inside of an existing virtual
|
||||
environment by including packages from the parent. Also,
|
||||
"ensurepip" is replaced if possible with just recreating pip's
|
||||
console_scripts inside the virtual environment.
|
||||
|
||||
Parameters for base class init:
|
||||
- system_site_packages: bool = False
|
||||
- clear: bool = False
|
||||
- symlinks: bool = False
|
||||
- upgrade: bool = False
|
||||
- with_pip: bool = False
|
||||
- prompt: Optional[str] = None
|
||||
- upgrade_deps: bool = False (Since 3.9)
|
||||
"""
|
||||
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
logger.debug("QemuEnvBuilder.__init__(...)")
|
||||
|
||||
# For nested venv emulation:
|
||||
self.use_parent_packages = False
|
||||
if inside_a_venv():
|
||||
# Include parent packages only if we're in a venv and
|
||||
# system_site_packages was True.
|
||||
self.use_parent_packages = kwargs.pop(
|
||||
"system_site_packages", False
|
||||
)
|
||||
# Include system_site_packages only when the parent,
|
||||
# The venv we are currently in, also does so.
|
||||
kwargs["system_site_packages"] = sys.base_prefix in site.PREFIXES
|
||||
|
||||
# ensurepip is slow: venv creation can be very fast for cases where
|
||||
# we allow the use of system_site_packages. Therefore, ensurepip is
|
||||
# replaced with our own script generation once the virtual environment
|
||||
# is setup.
|
||||
self.want_pip = kwargs.get("with_pip", False)
|
||||
if self.want_pip:
|
||||
if (
|
||||
kwargs.get("system_site_packages", False)
|
||||
and not need_ensurepip()
|
||||
):
|
||||
kwargs["with_pip"] = False
|
||||
else:
|
||||
check_ensurepip(suggest_remedy=True)
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Make the context available post-creation:
|
||||
self._context: Optional[SimpleNamespace] = None
|
||||
|
||||
def get_parent_libpath(self) -> Optional[str]:
|
||||
"""Return the libpath of the parent venv, if applicable."""
|
||||
if self.use_parent_packages:
|
||||
return sysconfig.get_path("purelib")
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def compute_venv_libpath(context: SimpleNamespace) -> str:
|
||||
"""
|
||||
Compatibility wrapper for context.lib_path for Python < 3.12
|
||||
"""
|
||||
# Python 3.12+, not strictly necessary because it's documented
|
||||
# to be the same as 3.10 code below:
|
||||
if sys.version_info >= (3, 12):
|
||||
return context.lib_path
|
||||
|
||||
# Python 3.10+
|
||||
if "venv" in sysconfig.get_scheme_names():
|
||||
lib_path = sysconfig.get_path(
|
||||
"purelib", scheme="venv", vars={"base": context.env_dir}
|
||||
)
|
||||
assert lib_path is not None
|
||||
return lib_path
|
||||
|
||||
# For Python <= 3.9 we need to hardcode this. Fortunately the
|
||||
# code below was the same in Python 3.6-3.10, so there is only
|
||||
# one case.
|
||||
if sys.platform == "win32":
|
||||
return os.path.join(context.env_dir, "Lib", "site-packages")
|
||||
return os.path.join(
|
||||
context.env_dir,
|
||||
"lib",
|
||||
"python%d.%d" % sys.version_info[:2],
|
||||
"site-packages",
|
||||
)
|
||||
|
||||
def ensure_directories(self, env_dir: DirType) -> SimpleNamespace:
|
||||
logger.debug("ensure_directories(env_dir=%s)", env_dir)
|
||||
self._context = super().ensure_directories(env_dir)
|
||||
return self._context
|
||||
|
||||
def create(self, env_dir: DirType) -> None:
|
||||
logger.debug("create(env_dir=%s)", env_dir)
|
||||
super().create(env_dir)
|
||||
assert self._context is not None
|
||||
self.post_post_setup(self._context)
|
||||
|
||||
def post_post_setup(self, context: SimpleNamespace) -> None:
|
||||
"""
|
||||
The final, final hook. Enter the venv and run commands inside of it.
|
||||
"""
|
||||
if self.use_parent_packages:
|
||||
# We're inside of a venv and we want to include the parent
|
||||
# venv's packages.
|
||||
parent_libpath = self.get_parent_libpath()
|
||||
assert parent_libpath is not None
|
||||
logger.debug("parent_libpath: %s", parent_libpath)
|
||||
|
||||
our_libpath = self.compute_venv_libpath(context)
|
||||
logger.debug("our_libpath: %s", our_libpath)
|
||||
|
||||
pth_file = os.path.join(our_libpath, "nested.pth")
|
||||
with open(pth_file, "w", encoding="UTF-8") as file:
|
||||
file.write(parent_libpath + os.linesep)
|
||||
|
||||
if self.want_pip:
|
||||
args = [
|
||||
context.env_exe,
|
||||
__file__,
|
||||
"post_init",
|
||||
]
|
||||
subprocess.run(args, check=True)
|
||||
|
||||
def get_value(self, field: str) -> str:
|
||||
"""
|
||||
Get a string value from the context namespace after a call to build.
|
||||
|
||||
For valid field names, see:
|
||||
https://docs.python.org/3/library/venv.html#venv.EnvBuilder.ensure_directories
|
||||
"""
|
||||
ret = getattr(self._context, field)
|
||||
assert isinstance(ret, str)
|
||||
return ret
|
||||
|
||||
|
||||
def need_ensurepip() -> bool:
|
||||
"""
|
||||
Tests for the presence of setuptools and pip.
|
||||
|
||||
:return: `True` if we do not detect both packages.
|
||||
"""
|
||||
# Don't try to actually import them, it's fraught with danger:
|
||||
# https://github.com/pypa/setuptools/issues/2993
|
||||
if find_spec("setuptools") and find_spec("pip"):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def check_ensurepip(prefix: str = "", suggest_remedy: bool = False) -> None:
|
||||
"""
|
||||
Check that we have ensurepip.
|
||||
|
||||
Raise a fatal exception with a helpful hint if it isn't available.
|
||||
"""
|
||||
if not find_spec("ensurepip"):
|
||||
msg = (
|
||||
"Python's ensurepip module is not found.\n"
|
||||
"It's normally part of the Python standard library, "
|
||||
"maybe your distribution packages it separately?\n"
|
||||
"(Debian puts ensurepip in its python3-venv package.)\n"
|
||||
)
|
||||
if suggest_remedy:
|
||||
msg += (
|
||||
"Either install ensurepip, or alleviate the need for it in the"
|
||||
" first place by installing pip and setuptools for "
|
||||
f"'{sys.executable}'.\n"
|
||||
)
|
||||
raise Ouch(prefix + msg)
|
||||
|
||||
# ensurepip uses pyexpat, which can also go missing on us:
|
||||
if not find_spec("pyexpat"):
|
||||
msg = (
|
||||
"Python's pyexpat module is not found.\n"
|
||||
"It's normally part of the Python standard library, "
|
||||
"maybe your distribution packages it separately?\n"
|
||||
"(NetBSD's pkgsrc debundles this to e.g. 'py310-expat'.)\n"
|
||||
)
|
||||
if suggest_remedy:
|
||||
msg += (
|
||||
"Either install pyexpat, or alleviate the need for it in the "
|
||||
"first place by installing pip and setuptools for "
|
||||
f"'{sys.executable}'.\n"
|
||||
)
|
||||
raise Ouch(prefix + msg)
|
||||
|
||||
|
||||
def make_venv( # pylint: disable=too-many-arguments
|
||||
env_dir: Union[str, Path],
|
||||
system_site_packages: bool = False,
|
||||
clear: bool = True,
|
||||
symlinks: Optional[bool] = None,
|
||||
with_pip: bool = True,
|
||||
) -> None:
|
||||
"""
|
||||
Create a venv using `QemuEnvBuilder`.
|
||||
|
||||
This is analogous to the `venv.create` module-level convenience
|
||||
function that is part of the Python stdblib, except it uses
|
||||
`QemuEnvBuilder` instead.
|
||||
|
||||
:param env_dir: The directory to create/install to.
|
||||
:param system_site_packages:
|
||||
Allow inheriting packages from the system installation.
|
||||
:param clear: When True, fully remove any prior venv and files.
|
||||
:param symlinks:
|
||||
Whether to use symlinks to the target interpreter or not. If
|
||||
left unspecified, it will use symlinks except on Windows to
|
||||
match behavior with the "venv" CLI tool.
|
||||
:param with_pip:
|
||||
Whether to install "pip" binaries or not.
|
||||
"""
|
||||
logger.debug(
|
||||
"%s: make_venv(env_dir=%s, system_site_packages=%s, "
|
||||
"clear=%s, symlinks=%s, with_pip=%s)",
|
||||
__file__,
|
||||
str(env_dir),
|
||||
system_site_packages,
|
||||
clear,
|
||||
symlinks,
|
||||
with_pip,
|
||||
)
|
||||
|
||||
if symlinks is None:
|
||||
# Default behavior of standard venv CLI
|
||||
symlinks = os.name != "nt"
|
||||
|
||||
builder = QemuEnvBuilder(
|
||||
system_site_packages=system_site_packages,
|
||||
clear=clear,
|
||||
symlinks=symlinks,
|
||||
with_pip=with_pip,
|
||||
)
|
||||
|
||||
style = "non-isolated" if builder.system_site_packages else "isolated"
|
||||
nested = ""
|
||||
if builder.use_parent_packages:
|
||||
nested = f"(with packages from '{builder.get_parent_libpath()}') "
|
||||
print(
|
||||
f"mkvenv: Creating {style} virtual environment"
|
||||
f" {nested}at '{str(env_dir)}'",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
try:
|
||||
logger.debug("Invoking builder.create()")
|
||||
try:
|
||||
builder.create(str(env_dir))
|
||||
except SystemExit as exc:
|
||||
# Some versions of the venv module raise SystemExit; *nasty*!
|
||||
# We want the exception that prompted it. It might be a subprocess
|
||||
# error that has output we *really* want to see.
|
||||
logger.debug("Intercepted SystemExit from EnvBuilder.create()")
|
||||
raise exc.__cause__ or exc.__context__ or exc
|
||||
logger.debug("builder.create() finished")
|
||||
except subprocess.CalledProcessError as exc:
|
||||
logger.error("mkvenv subprocess failed:")
|
||||
logger.error("cmd: %s", exc.cmd)
|
||||
logger.error("returncode: %d", exc.returncode)
|
||||
|
||||
def _stringify(data: Union[str, bytes]) -> str:
|
||||
if isinstance(data, bytes):
|
||||
return data.decode()
|
||||
return data
|
||||
|
||||
lines = []
|
||||
if exc.stdout:
|
||||
lines.append("========== stdout ==========")
|
||||
lines.append(_stringify(exc.stdout))
|
||||
lines.append("============================")
|
||||
if exc.stderr:
|
||||
lines.append("========== stderr ==========")
|
||||
lines.append(_stringify(exc.stderr))
|
||||
lines.append("============================")
|
||||
if lines:
|
||||
logger.error(os.linesep.join(lines))
|
||||
|
||||
raise Ouch("VENV creation subprocess failed.") from exc
|
||||
|
||||
# print the python executable to stdout for configure.
|
||||
print(builder.get_value("env_exe"))
|
||||
|
||||
|
||||
def _gen_importlib(packages: Sequence[str]) -> Iterator[str]:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
# pylint: disable=no-name-in-module
|
||||
# pylint: disable=import-error
|
||||
try:
|
||||
# First preference: Python 3.8+ stdlib
|
||||
from importlib.metadata import ( # type: ignore
|
||||
PackageNotFoundError,
|
||||
distribution,
|
||||
)
|
||||
except ImportError as exc:
|
||||
logger.debug("%s", str(exc))
|
||||
# Second preference: Commonly available PyPI backport
|
||||
from importlib_metadata import ( # type: ignore
|
||||
PackageNotFoundError,
|
||||
distribution,
|
||||
)
|
||||
|
||||
def _generator() -> Iterator[str]:
|
||||
for package in packages:
|
||||
try:
|
||||
entry_points = distribution(package).entry_points
|
||||
except PackageNotFoundError:
|
||||
continue
|
||||
|
||||
# The EntryPoints type is only available in 3.10+,
|
||||
# treat this as a vanilla list and filter it ourselves.
|
||||
entry_points = filter(
|
||||
lambda ep: ep.group == "console_scripts", entry_points
|
||||
)
|
||||
|
||||
for entry_point in entry_points:
|
||||
yield f"{entry_point.name} = {entry_point.value}"
|
||||
|
||||
return _generator()
|
||||
|
||||
|
||||
def _gen_pkg_resources(packages: Sequence[str]) -> Iterator[str]:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
# Bundled with setuptools; has a good chance of being available.
|
||||
import pkg_resources
|
||||
|
||||
def _generator() -> Iterator[str]:
|
||||
for package in packages:
|
||||
try:
|
||||
eps = pkg_resources.get_entry_map(package, "console_scripts")
|
||||
except pkg_resources.DistributionNotFound:
|
||||
continue
|
||||
|
||||
for entry_point in eps.values():
|
||||
yield str(entry_point)
|
||||
|
||||
return _generator()
|
||||
|
||||
|
||||
def generate_console_scripts(
|
||||
packages: Sequence[str],
|
||||
python_path: Optional[str] = None,
|
||||
bin_path: Optional[str] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Generate script shims for console_script entry points in @packages.
|
||||
"""
|
||||
if python_path is None:
|
||||
python_path = sys.executable
|
||||
if bin_path is None:
|
||||
bin_path = sysconfig.get_path("scripts")
|
||||
assert bin_path is not None
|
||||
|
||||
logger.debug(
|
||||
"generate_console_scripts(packages=%s, python_path=%s, bin_path=%s)",
|
||||
packages,
|
||||
python_path,
|
||||
bin_path,
|
||||
)
|
||||
|
||||
if not packages:
|
||||
return
|
||||
|
||||
def _get_entry_points() -> Iterator[str]:
|
||||
"""Python 3.7 compatibility shim for iterating entry points."""
|
||||
# Python 3.8+, or Python 3.7 with importlib_metadata installed.
|
||||
try:
|
||||
return _gen_importlib(packages)
|
||||
except ImportError as exc:
|
||||
logger.debug("%s", str(exc))
|
||||
|
||||
# Python 3.7 with setuptools installed.
|
||||
try:
|
||||
return _gen_pkg_resources(packages)
|
||||
except ImportError as exc:
|
||||
logger.debug("%s", str(exc))
|
||||
raise Ouch(
|
||||
"Neither importlib.metadata nor pkg_resources found, "
|
||||
"can't generate console script shims.\n"
|
||||
"Use Python 3.8+, or install importlib-metadata or setuptools."
|
||||
) from exc
|
||||
|
||||
maker = distlib.scripts.ScriptMaker(None, bin_path)
|
||||
maker.variants = {""}
|
||||
maker.clobber = False
|
||||
|
||||
for entry_point in _get_entry_points():
|
||||
for filename in maker.make(entry_point):
|
||||
logger.debug("wrote console_script '%s'", filename)
|
||||
|
||||
|
||||
def checkpip() -> bool:
|
||||
"""
|
||||
Debian10 has a pip that's broken when used inside of a virtual environment.
|
||||
|
||||
We try to detect and correct that case here.
|
||||
"""
|
||||
try:
|
||||
# pylint: disable=import-outside-toplevel,unused-import,import-error
|
||||
# pylint: disable=redefined-outer-name
|
||||
import pip._internal # type: ignore # noqa: F401
|
||||
|
||||
logger.debug("pip appears to be working correctly.")
|
||||
return False
|
||||
except ModuleNotFoundError as exc:
|
||||
if exc.name == "pip._internal":
|
||||
# Uh, fair enough. They did say "internal".
|
||||
# Let's just assume it's fine.
|
||||
return False
|
||||
logger.warning("pip appears to be malfunctioning: %s", str(exc))
|
||||
|
||||
check_ensurepip("pip appears to be non-functional, and ")
|
||||
|
||||
logger.debug("Attempting to repair pip ...")
|
||||
subprocess.run(
|
||||
(sys.executable, "-m", "ensurepip"),
|
||||
stdout=subprocess.DEVNULL,
|
||||
check=True,
|
||||
)
|
||||
logger.debug("Pip is now (hopefully) repaired!")
|
||||
return True
|
||||
|
||||
|
||||
def pkgname_from_depspec(dep_spec: str) -> str:
|
||||
"""
|
||||
Parse package name out of a PEP-508 depspec.
|
||||
|
||||
See https://peps.python.org/pep-0508/#names
|
||||
"""
|
||||
match = re.match(
|
||||
r"^([A-Z0-9]([A-Z0-9._-]*[A-Z0-9])?)", dep_spec, re.IGNORECASE
|
||||
)
|
||||
if not match:
|
||||
raise ValueError(
|
||||
f"dep_spec '{dep_spec}'"
|
||||
" does not appear to contain a valid package name"
|
||||
)
|
||||
return match.group(0)
|
||||
|
||||
|
||||
def diagnose(
|
||||
dep_spec: str,
|
||||
online: bool,
|
||||
wheels_dir: Optional[Union[str, Path]],
|
||||
prog: Optional[str],
|
||||
) -> Tuple[str, bool]:
|
||||
"""
|
||||
Offer a summary to the user as to why a package failed to be installed.
|
||||
|
||||
:param dep_spec: The package we tried to ensure, e.g. 'meson>=0.61.5'
|
||||
:param online: Did we allow PyPI access?
|
||||
:param prog:
|
||||
Optionally, a shell program name that can be used as a
|
||||
bellwether to detect if this program is installed elsewhere on
|
||||
the system. This is used to offer advice when a program is
|
||||
detected for a different python version.
|
||||
:param wheels_dir:
|
||||
Optionally, a directory that was searched for vendored packages.
|
||||
"""
|
||||
# pylint: disable=too-many-branches
|
||||
|
||||
# Some errors are not particularly serious
|
||||
bad = False
|
||||
|
||||
pkg_name = pkgname_from_depspec(dep_spec)
|
||||
pkg_version = None
|
||||
|
||||
has_importlib = False
|
||||
try:
|
||||
# Python 3.8+ stdlib
|
||||
# pylint: disable=import-outside-toplevel
|
||||
# pylint: disable=no-name-in-module
|
||||
# pylint: disable=import-error
|
||||
from importlib.metadata import ( # type: ignore
|
||||
PackageNotFoundError,
|
||||
version,
|
||||
)
|
||||
|
||||
has_importlib = True
|
||||
try:
|
||||
pkg_version = version(pkg_name)
|
||||
except PackageNotFoundError:
|
||||
pass
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
|
||||
lines = []
|
||||
|
||||
if pkg_version:
|
||||
lines.append(
|
||||
f"Python package '{pkg_name}' version '{pkg_version}' was found,"
|
||||
" but isn't suitable."
|
||||
)
|
||||
elif has_importlib:
|
||||
lines.append(
|
||||
f"Python package '{pkg_name}' was not found nor installed."
|
||||
)
|
||||
else:
|
||||
lines.append(
|
||||
f"Python package '{pkg_name}' is either not found or"
|
||||
" not a suitable version."
|
||||
)
|
||||
|
||||
if wheels_dir:
|
||||
lines.append(
|
||||
"No suitable version found in, or failed to install from"
|
||||
f" '{wheels_dir}'."
|
||||
)
|
||||
bad = True
|
||||
|
||||
if online:
|
||||
lines.append("A suitable version could not be obtained from PyPI.")
|
||||
bad = True
|
||||
else:
|
||||
lines.append(
|
||||
"mkvenv was configured to operate offline and did not check PyPI."
|
||||
)
|
||||
|
||||
if prog and not pkg_version:
|
||||
which = shutil.which(prog)
|
||||
if which:
|
||||
if sys.base_prefix in site.PREFIXES:
|
||||
pypath = Path(sys.executable).resolve()
|
||||
lines.append(
|
||||
f"'{prog}' was detected on your system at '{which}', "
|
||||
f"but the Python package '{pkg_name}' was not found by "
|
||||
f"this Python interpreter ('{pypath}'). "
|
||||
f"Typically this means that '{prog}' has been installed "
|
||||
"against a different Python interpreter on your system."
|
||||
)
|
||||
else:
|
||||
lines.append(
|
||||
f"'{prog}' was detected on your system at '{which}', "
|
||||
"but the build is using an isolated virtual environment."
|
||||
)
|
||||
bad = True
|
||||
|
||||
lines = [f" • {line}" for line in lines]
|
||||
if bad:
|
||||
lines.insert(0, f"Could not provide build dependency '{dep_spec}':")
|
||||
else:
|
||||
lines.insert(0, f"'{dep_spec}' not found:")
|
||||
return os.linesep.join(lines), bad
|
||||
|
||||
|
||||
def pip_install(
|
||||
args: Sequence[str],
|
||||
online: bool = False,
|
||||
wheels_dir: Optional[Union[str, Path]] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Use pip to install a package or package(s) as specified in @args.
|
||||
"""
|
||||
loud = bool(
|
||||
os.environ.get("DEBUG")
|
||||
or os.environ.get("GITLAB_CI")
|
||||
or os.environ.get("V")
|
||||
)
|
||||
|
||||
full_args = [
|
||||
sys.executable,
|
||||
"-m",
|
||||
"pip",
|
||||
"install",
|
||||
"--disable-pip-version-check",
|
||||
"-v" if loud else "-q",
|
||||
]
|
||||
if not online:
|
||||
full_args += ["--no-index"]
|
||||
if wheels_dir:
|
||||
full_args += ["--find-links", f"file://{str(wheels_dir)}"]
|
||||
full_args += list(args)
|
||||
subprocess.run(
|
||||
full_args,
|
||||
check=True,
|
||||
)
|
||||
|
||||
|
||||
def _do_ensure(
|
||||
dep_specs: Sequence[str],
|
||||
online: bool = False,
|
||||
wheels_dir: Optional[Union[str, Path]] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Use pip to ensure we have the package specified by @dep_specs.
|
||||
|
||||
If the package is already installed, do nothing. If online and
|
||||
wheels_dir are both provided, prefer packages found in wheels_dir
|
||||
first before connecting to PyPI.
|
||||
|
||||
:param dep_specs:
|
||||
PEP 508 dependency specifications. e.g. ['meson>=0.61.5'].
|
||||
:param online: If True, fall back to PyPI.
|
||||
:param wheels_dir: If specified, search this path for packages.
|
||||
"""
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings(
|
||||
"ignore", category=UserWarning, module="distlib"
|
||||
)
|
||||
dist_path = distlib.database.DistributionPath(include_egg=True)
|
||||
absent = []
|
||||
present = []
|
||||
for spec in dep_specs:
|
||||
matcher = distlib.version.LegacyMatcher(spec)
|
||||
dist = dist_path.get_distribution(matcher.name)
|
||||
if dist is None or not matcher.match(dist.version):
|
||||
absent.append(spec)
|
||||
else:
|
||||
logger.info("found %s", dist)
|
||||
present.append(matcher.name)
|
||||
|
||||
if present:
|
||||
generate_console_scripts(present)
|
||||
|
||||
if absent:
|
||||
# Some packages are missing or aren't a suitable version,
|
||||
# install a suitable (possibly vendored) package.
|
||||
print(f"mkvenv: installing {', '.join(absent)}", file=sys.stderr)
|
||||
pip_install(args=absent, online=online, wheels_dir=wheels_dir)
|
||||
|
||||
|
||||
def ensure(
|
||||
dep_specs: Sequence[str],
|
||||
online: bool = False,
|
||||
wheels_dir: Optional[Union[str, Path]] = None,
|
||||
prog: Optional[str] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Use pip to ensure we have the package specified by @dep_specs.
|
||||
|
||||
If the package is already installed, do nothing. If online and
|
||||
wheels_dir are both provided, prefer packages found in wheels_dir
|
||||
first before connecting to PyPI.
|
||||
|
||||
:param dep_specs:
|
||||
PEP 508 dependency specifications. e.g. ['meson>=0.61.5'].
|
||||
:param online: If True, fall back to PyPI.
|
||||
:param wheels_dir: If specified, search this path for packages.
|
||||
:param prog:
|
||||
If specified, use this program name for error diagnostics that will
|
||||
be presented to the user. e.g., 'sphinx-build' can be used as a
|
||||
bellwether for the presence of 'sphinx'.
|
||||
"""
|
||||
print(f"mkvenv: checking for {', '.join(dep_specs)}", file=sys.stderr)
|
||||
|
||||
if not HAVE_DISTLIB:
|
||||
raise Ouch("a usable distlib could not be found, please install it")
|
||||
|
||||
try:
|
||||
_do_ensure(dep_specs, online, wheels_dir)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
# Well, that's not good.
|
||||
msg, bad = diagnose(dep_specs[0], online, wheels_dir, prog)
|
||||
if bad:
|
||||
raise Ouch(msg) from exc
|
||||
raise SystemExit(f"\n{msg}\n\n") from exc
|
||||
|
||||
|
||||
def post_venv_setup() -> None:
|
||||
"""
|
||||
This is intended to be run *inside the venv* after it is created.
|
||||
"""
|
||||
logger.debug("post_venv_setup()")
|
||||
# Test for a broken pip (Debian 10 or derivative?) and fix it if needed
|
||||
if not checkpip():
|
||||
# Finally, generate a 'pip' script so the venv is usable in a normal
|
||||
# way from the CLI. This only happens when we inherited pip from a
|
||||
# parent/system-site and haven't run ensurepip in some way.
|
||||
generate_console_scripts(["pip"])
|
||||
|
||||
|
||||
def _add_create_subcommand(subparsers: Any) -> None:
|
||||
subparser = subparsers.add_parser("create", help="create a venv")
|
||||
subparser.add_argument(
|
||||
"target",
|
||||
type=str,
|
||||
action="store",
|
||||
help="Target directory to install virtual environment into.",
|
||||
)
|
||||
|
||||
|
||||
def _add_post_init_subcommand(subparsers: Any) -> None:
|
||||
subparsers.add_parser("post_init", help="post-venv initialization")
|
||||
|
||||
|
||||
def _add_ensure_subcommand(subparsers: Any) -> None:
|
||||
subparser = subparsers.add_parser(
|
||||
"ensure", help="Ensure that the specified package is installed."
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--online",
|
||||
action="store_true",
|
||||
help="Install packages from PyPI, if necessary.",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--dir",
|
||||
type=str,
|
||||
action="store",
|
||||
help="Path to vendored packages where we may install from.",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--diagnose",
|
||||
type=str,
|
||||
action="store",
|
||||
help=(
|
||||
"Name of a shell utility to use for "
|
||||
"diagnostics if this command fails."
|
||||
),
|
||||
)
|
||||
subparser.add_argument(
|
||||
"dep_specs",
|
||||
type=str,
|
||||
action="store",
|
||||
help="PEP 508 Dependency specification, e.g. 'meson>=0.61.5'",
|
||||
nargs="+",
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
"""CLI interface to make_qemu_venv. See module docstring."""
|
||||
if os.environ.get("DEBUG") or os.environ.get("GITLAB_CI"):
|
||||
# You're welcome.
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
else:
|
||||
if os.environ.get("V"):
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
# These are incredibly noisy even for V=1
|
||||
logging.getLogger("distlib.metadata").addFilter(lambda record: False)
|
||||
logging.getLogger("distlib.database").addFilter(lambda record: False)
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="mkvenv",
|
||||
description="QEMU pyvenv bootstrapping utility",
|
||||
)
|
||||
subparsers = parser.add_subparsers(
|
||||
title="Commands",
|
||||
dest="command",
|
||||
required=True,
|
||||
metavar="command",
|
||||
help="Description",
|
||||
)
|
||||
|
||||
_add_create_subcommand(subparsers)
|
||||
_add_post_init_subcommand(subparsers)
|
||||
_add_ensure_subcommand(subparsers)
|
||||
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
if args.command == "create":
|
||||
make_venv(
|
||||
args.target,
|
||||
system_site_packages=True,
|
||||
clear=True,
|
||||
)
|
||||
if args.command == "post_init":
|
||||
post_venv_setup()
|
||||
if args.command == "ensure":
|
||||
ensure(
|
||||
dep_specs=args.dep_specs,
|
||||
online=args.online,
|
||||
wheels_dir=args.dir,
|
||||
prog=args.diagnose,
|
||||
)
|
||||
logger.debug("mkvenv.py %s: exiting", args.command)
|
||||
except Ouch as exc:
|
||||
print("\n*** Ouch! ***\n", file=sys.stderr)
|
||||
print(str(exc), "\n\n", file=sys.stderr)
|
||||
return 1
|
||||
except SystemExit:
|
||||
raise
|
||||
except: # pylint: disable=bare-except
|
||||
logger.exception("mkvenv did not complete successfully:")
|
||||
return 2
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
74
python/scripts/vendor.py
Executable file
74
python/scripts/vendor.py
Executable file
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
vendor - QEMU python vendoring utility
|
||||
|
||||
usage: vendor [-h]
|
||||
|
||||
QEMU python vendoring utility
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
"""
|
||||
|
||||
# Copyright (C) 2023 Red Hat, Inc.
|
||||
#
|
||||
# Authors:
|
||||
# John Snow <jsnow@redhat.com>
|
||||
#
|
||||
# This work is licensed under the terms of the GNU GPL, version 2 or
|
||||
# later. See the COPYING file in the top-level directory.
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
|
||||
def main() -> int:
|
||||
"""Run the vendoring utility. See module-level docstring."""
|
||||
loud = False
|
||||
if os.environ.get("DEBUG") or os.environ.get("V"):
|
||||
loud = True
|
||||
|
||||
# No options or anything for now, but I guess
|
||||
# you'll figure that out when you run --help.
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="vendor",
|
||||
description="QEMU python vendoring utility",
|
||||
)
|
||||
parser.parse_args()
|
||||
|
||||
packages = {
|
||||
"meson==0.63.3":
|
||||
"d677b809c4895dcbaac9bf6c43703fcb3609a4b24c6057c78f828590049cf43a",
|
||||
}
|
||||
|
||||
vendor_dir = Path(__file__, "..", "..", "wheels").resolve()
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8") as file:
|
||||
for dep_spec, checksum in packages.items():
|
||||
file.write(f"{dep_spec} --hash=sha256:{checksum}")
|
||||
file.flush()
|
||||
|
||||
cli_args = [
|
||||
"pip",
|
||||
"download",
|
||||
"--dest",
|
||||
str(vendor_dir),
|
||||
"--require-hashes",
|
||||
"-r",
|
||||
file.name,
|
||||
]
|
||||
if loud:
|
||||
cli_args.append("-v")
|
||||
|
||||
print(" ".join(cli_args))
|
||||
subprocess.run(cli_args, check=True)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
@ -14,7 +14,6 @@ classifiers =
|
||||
Natural Language :: English
|
||||
Operating System :: OS Independent
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
@ -23,7 +22,7 @@ classifiers =
|
||||
Typing :: Typed
|
||||
|
||||
[options]
|
||||
python_requires = >= 3.6
|
||||
python_requires = >= 3.7
|
||||
packages =
|
||||
qemu.qmp
|
||||
qemu.machine
|
||||
@ -36,11 +35,12 @@ packages =
|
||||
# Remember to update tests/minreqs.txt if changing anything below:
|
||||
devel =
|
||||
avocado-framework >= 90.0
|
||||
flake8 >= 3.6.0
|
||||
distlib >= 0.3.6
|
||||
flake8 >= 5.0.4
|
||||
fusepy >= 2.0.4
|
||||
isort >= 5.1.2
|
||||
mypy >= 0.780
|
||||
pylint >= 2.8.0
|
||||
pylint >= 2.17.3
|
||||
tox >= 3.18.0
|
||||
urwid >= 2.1.2
|
||||
urwid-readline >= 0.13
|
||||
@ -76,7 +76,7 @@ exclude = __pycache__,
|
||||
|
||||
[mypy]
|
||||
strict = True
|
||||
python_version = 3.6
|
||||
python_version = 3.7
|
||||
warn_unused_configs = True
|
||||
namespace_packages = True
|
||||
warn_unused_ignores = False
|
||||
@ -103,6 +103,39 @@ ignore_missing_imports = True
|
||||
[mypy-pygments]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-importlib.metadata]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-importlib_metadata]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-pkg_resources]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-distlib]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-distlib.database]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-distlib.scripts]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-distlib.version]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-pip._vendor.distlib]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-pip._vendor.distlib.database]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-pip._vendor.distlib.scripts]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-pip._vendor.distlib.version]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[pylint.messages control]
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
@ -132,6 +165,7 @@ good-names=i,
|
||||
fd, # fd = os.open(...)
|
||||
c, # for c in string: ...
|
||||
T, # for TypeVars. See pylint#3401
|
||||
SocketAddrT, # Not sure why this is invalid.
|
||||
|
||||
[pylint.similarities]
|
||||
# Ignore imports when computing similarities.
|
||||
@ -158,7 +192,7 @@ multi_line_output=3
|
||||
# of python available on your system to run this test.
|
||||
|
||||
[tox:tox]
|
||||
envlist = py36, py37, py38, py39, py310, py311
|
||||
envlist = py37, py38, py39, py310, py311
|
||||
skip_missing_interpreters = true
|
||||
|
||||
[testenv]
|
||||
|
@ -1,2 +1,3 @@
|
||||
#!/bin/sh -e
|
||||
python3 -m flake8 qemu/
|
||||
python3 -m flake8 scripts/
|
||||
|
@ -1,2 +1,3 @@
|
||||
#!/bin/sh -e
|
||||
python3 -m isort -c qemu/
|
||||
python3 -m isort -c scripts/
|
||||
|
@ -1,5 +1,5 @@
|
||||
# This file lists the ***oldest possible dependencies*** needed to run
|
||||
# "make check" successfully under ***Python 3.6***. It is used primarily
|
||||
# "make check" successfully under ***Python 3.7***. It is used primarily
|
||||
# by GitLab CI to ensure that our stated minimum versions in setup.cfg
|
||||
# are truthful and regularly validated.
|
||||
#
|
||||
@ -16,6 +16,9 @@ urwid==2.1.2
|
||||
urwid-readline==0.13
|
||||
Pygments==2.9.0
|
||||
|
||||
# Dependencies for mkvenv
|
||||
distlib==0.3.6
|
||||
|
||||
# Dependencies for FUSE support for qom-fuse
|
||||
fusepy==2.0.4
|
||||
|
||||
@ -23,23 +26,23 @@ fusepy==2.0.4
|
||||
avocado-framework==90.0
|
||||
|
||||
# Linters
|
||||
flake8==3.6.0
|
||||
flake8==5.0.4
|
||||
isort==5.1.2
|
||||
mypy==0.780
|
||||
pylint==2.8.0
|
||||
pylint==2.17.3
|
||||
|
||||
# Transitive flake8 dependencies
|
||||
mccabe==0.6.0
|
||||
pycodestyle==2.4.0
|
||||
pyflakes==2.0.0
|
||||
mccabe==0.7.0
|
||||
pycodestyle==2.9.1
|
||||
pyflakes==2.5.0
|
||||
|
||||
# Transitive mypy dependencies
|
||||
mypy-extensions==0.4.3
|
||||
typed-ast==1.4.0
|
||||
typing-extensions==3.7.4
|
||||
typing-extensions==4.5.0
|
||||
|
||||
# Transitive pylint dependencies
|
||||
astroid==2.5.4
|
||||
astroid==2.15.4
|
||||
lazy-object-proxy==1.4.0
|
||||
toml==0.10.0
|
||||
wrapt==1.12.1
|
||||
|
@ -1,2 +1,3 @@
|
||||
#!/bin/sh -e
|
||||
python3 -m mypy -p qemu
|
||||
python3 -m mypy scripts/
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/sh -e
|
||||
# See commit message for environment variable explainer.
|
||||
SETUPTOOLS_USE_DISTUTILS=stdlib python3 -m pylint qemu/
|
||||
SETUPTOOLS_USE_DISTUTILS=stdlib python3 -m pylint scripts/
|
||||
|
BIN
python/wheels/meson-0.63.3-py3-none-any.whl
Normal file
BIN
python/wheels/meson-0.63.3-py3-none-any.whl
Normal file
Binary file not shown.
@ -22,7 +22,7 @@ have_qga_vss = get_option('qga_vss') \
|
||||
Then run configure with: --extra-cxxflags="-isystem /path/to/vss/inc/win2003"''') \
|
||||
.require(midl.found() or widl.found(),
|
||||
error_message: 'VSS support requires midl or widl') \
|
||||
.require(not enable_static,
|
||||
.require(not get_option('prefer_static'),
|
||||
error_message: 'VSS support requires dynamic linking with GLib') \
|
||||
.allowed()
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
# KVM and x86_64, or tests that are generic enough to be valid for all
|
||||
# targets. Such a test list can be generated with:
|
||||
#
|
||||
# ./tests/venv/bin/avocado list --filter-by-tags-include-empty \
|
||||
# ./pyvenv/bin/avocado list --filter-by-tags-include-empty \
|
||||
# --filter-by-tags-include-empty-key -t accel:kvm,arch:x86_64 \
|
||||
# tests/avocado/
|
||||
#
|
||||
@ -22,7 +22,7 @@
|
||||
# - tests/avocado/virtio_check_params.py:VirtioMaxSegSettingsCheck.test_machine_types
|
||||
#
|
||||
make get-vm-images
|
||||
./tests/venv/bin/avocado run \
|
||||
./pyvenv/bin/avocado run \
|
||||
--job-results-dir=tests/results/ \
|
||||
tests/avocado/boot_linux.py:BootLinuxX8664.test_pc_i440fx_kvm \
|
||||
tests/avocado/boot_linux.py:BootLinuxX8664.test_pc_q35_kvm \
|
||||
|
@ -24,6 +24,9 @@ hppa
|
||||
i386
|
||||
~ (/qemu)?((/include)?/hw/i386/.*|/target/i386/.*|/hw/intc/[^/]*apic[^/]*\.c)
|
||||
|
||||
loongarch
|
||||
~ (/qemu)?((/include)?/hw/(loongarch/.*|.*/loongarch.*)|/target/loongarch/.*)
|
||||
|
||||
m68k
|
||||
~ (/qemu)?((/include)?/hw/m68k/.*|/target/m68k/.*|(/include)?/hw(/.*)?/mcf.*|(/include)?/hw/nubus/.*)
|
||||
|
||||
@ -36,11 +39,14 @@ mips
|
||||
nios2
|
||||
~ (/qemu)?((/include)?/hw/nios2/.*|/target/nios2/.*)
|
||||
|
||||
openrisc
|
||||
~ (/qemu)?((/include)?/hw/openrisc/.*|/target/openrisc/.*)
|
||||
|
||||
ppc
|
||||
~ (/qemu)?((/include)?/hw/ppc/.*|/target/ppc/.*|/hw/pci-host/(uninorth.*|dec.*|prep.*|ppc.*)|/hw/misc/macio/.*|(/include)?/hw/.*/(xics|openpic|spapr).*)
|
||||
|
||||
riscv
|
||||
~ (/qemu)?((/include)?/hw/riscv/.*|/target/riscv/.*)
|
||||
~ (/qemu)?((/include)?/hw/riscv/.*|/target/riscv/.*|/hw/.*/(riscv_|ibex_|sifive_).*)
|
||||
|
||||
rx
|
||||
~ (/qemu)?((/include)?/hw/rx/.*|/target/rx/.*)
|
||||
@ -54,12 +60,12 @@ sh4
|
||||
sparc
|
||||
~ (/qemu)?((/include)?/hw/sparc(64)?.*|/target/sparc/.*|/hw/.*/grlib.*|/hw/display/cg3.c)
|
||||
|
||||
tilegx
|
||||
~ (/qemu)?(/target/tilegx/.*)
|
||||
|
||||
tricore
|
||||
~ (/qemu)?((/include)?/hw/tricore/.*|/target/tricore/.*)
|
||||
|
||||
xtensa
|
||||
~ (/qemu)?((/include)?/hw/xtensa/.*|/target/xtensa/.*)
|
||||
|
||||
9pfs
|
||||
~ (/qemu)?(/hw/9pfs/.*|/fsdev/.*)
|
||||
|
||||
@ -73,7 +79,7 @@ char
|
||||
~ (/qemu)?(/qemu-char\.c|/include/sysemu/char\.h|(/include)?/hw/char/.*)
|
||||
|
||||
crypto
|
||||
~ (/qemu)?((/include)?/crypto/.*|/hw/.*/crypto.*)
|
||||
~ (/qemu)?((/include)?/crypto/.*|/hw/.*/.*crypto.*|(/include/sysemu|/backends)/cryptodev.*)
|
||||
|
||||
disas
|
||||
~ (/qemu)?((/include)?/disas.*)
|
||||
@ -100,7 +106,7 @@ net
|
||||
~ (/qemu)?((/include)?(/hw)?/(net|rdma)/.*)
|
||||
|
||||
pci
|
||||
~ (/qemu)?(/hw/pci.*|/include/hw/pci.*)
|
||||
~ (/qemu)?(/include)?/hw/(cxl/|pci).*
|
||||
|
||||
qemu-ga
|
||||
~ (/qemu)?(/qga/.*)
|
||||
@ -108,9 +114,6 @@ qemu-ga
|
||||
scsi
|
||||
~ (/qemu)?(/scsi/.*|/hw/scsi/.*|/include/hw/scsi/.*)
|
||||
|
||||
tcg
|
||||
~ (/qemu)?(/accel/tcg/.*|/replay/.*|/(.*/)?softmmu.*)
|
||||
|
||||
trace
|
||||
~ (/qemu)?(/.*trace.*\.[ch])
|
||||
|
||||
@ -126,9 +129,27 @@ user
|
||||
util
|
||||
~ (/qemu)?(/util/.*|/include/qemu/.*)
|
||||
|
||||
vfio
|
||||
~ (/qemu)?(/include)?/hw/vfio/.*
|
||||
|
||||
virtio
|
||||
~ (/qemu)?(/include)?/hw/virtio/.*
|
||||
|
||||
xen
|
||||
~ (/qemu)?(.*/xen.*)
|
||||
|
||||
hvf
|
||||
~ (/qemu)?(.*/hvf.*)
|
||||
|
||||
kvm
|
||||
~ (/qemu)?(.*/kvm.*)
|
||||
|
||||
tcg
|
||||
~ (/qemu)?(/accel/tcg|/replay|/tcg)/.*
|
||||
|
||||
sysemu
|
||||
~ (/qemu)?(/softmmu/.*|/accel/.*)
|
||||
|
||||
(headers)
|
||||
~ (/qemu)?(/include/.*)
|
||||
|
||||
@ -137,9 +158,3 @@ testlibs
|
||||
|
||||
tests
|
||||
~ (/qemu)?(/tests/.*)
|
||||
|
||||
loongarch
|
||||
~ (/qemu)?((/include)?/hw/(loongarch/.*|.*/loongarch.*)|/target/loongarch/.*)
|
||||
|
||||
riscv
|
||||
~ (/qemu)?((/include)?/hw/riscv/.*|/target/riscv/.*|/hw/.*/(riscv_|ibex_|sifive_).*)
|
||||
|
@ -43,7 +43,7 @@ except ModuleNotFoundError as exc:
|
||||
print(f"Module '{exc.name}' not found.")
|
||||
print(" Try 'make check-venv' from your build directory,")
|
||||
print(" and then one way to run this script is like so:")
|
||||
print(f' > $builddir/tests/venv/bin/python3 "{path}"')
|
||||
print(f' > $builddir/pyvenv/bin/python3 "{path}"')
|
||||
sys.exit(1)
|
||||
|
||||
logger = logging.getLogger('device-crash-test')
|
||||
|
@ -35,6 +35,8 @@ SKIP_OPTIONS = {
|
||||
OPTION_NAMES = {
|
||||
"b_coverage": "gcov",
|
||||
"b_lto": "lto",
|
||||
"coroutine_backend": "with-coroutine",
|
||||
"debug": "debug-info",
|
||||
"malloc": "enable-malloc",
|
||||
"pkgversion": "with-pkgversion",
|
||||
"qemu_firmwarepath": "firmwarepath",
|
||||
@ -46,6 +48,7 @@ BUILTIN_OPTIONS = {
|
||||
"b_coverage",
|
||||
"b_lto",
|
||||
"datadir",
|
||||
"debug",
|
||||
"includedir",
|
||||
"libdir",
|
||||
"libexecdir",
|
||||
|
@ -1,8 +1,8 @@
|
||||
# This file is generated by meson-buildoptions.py, do not edit!
|
||||
meson_options_help() {
|
||||
printf "%s\n" ' --audio-drv-list=CHOICES Set audio driver list [default] (choices: al'
|
||||
printf "%s\n" ' sa/coreaudio/default/dsound/jack/oss/pa/'
|
||||
printf "%s\n" ' pipewire/sdl/sndio)'
|
||||
printf "%s\n" ' --audio-drv-list=CHOICES Set audio driver list [default] (choices: alsa/co'
|
||||
printf "%s\n" ' reaudio/default/dsound/jack/oss/pa/pipewire/sdl/s'
|
||||
printf "%s\n" ' ndio)'
|
||||
printf "%s\n" ' --block-drv-ro-whitelist=VALUE'
|
||||
printf "%s\n" ' set block driver read-only whitelist (by default'
|
||||
printf "%s\n" ' affects only QEMU, not tools like qemu-img)'
|
||||
@ -11,6 +11,7 @@ meson_options_help() {
|
||||
printf "%s\n" ' affects only QEMU, not tools like qemu-img)'
|
||||
printf "%s\n" ' --datadir=VALUE Data file directory [share]'
|
||||
printf "%s\n" ' --disable-coroutine-pool coroutine freelist (better performance)'
|
||||
printf "%s\n" ' --disable-debug-info Enable debug symbols and other information'
|
||||
printf "%s\n" ' --disable-hexagon-idef-parser'
|
||||
printf "%s\n" ' use idef-parser to automatically generate TCG'
|
||||
printf "%s\n" ' code for the Hexagon frontend'
|
||||
@ -41,11 +42,15 @@ meson_options_help() {
|
||||
printf "%s\n" ' --enable-profiler profiler support'
|
||||
printf "%s\n" ' --enable-rng-none dummy RNG, avoid using /dev/(u)random and'
|
||||
printf "%s\n" ' getrandom()'
|
||||
printf "%s\n" ' --enable-safe-stack SafeStack Stack Smash Protection (requires'
|
||||
printf "%s\n" ' clang/llvm and coroutine backend ucontext)'
|
||||
printf "%s\n" ' --enable-sanitizers enable default sanitizers'
|
||||
printf "%s\n" ' --enable-strip Strip targets on install'
|
||||
printf "%s\n" ' --enable-tcg-interpreter TCG with bytecode interpreter (slow)'
|
||||
printf "%s\n" ' --enable-trace-backends=CHOICES'
|
||||
printf "%s\n" ' Set available tracing backends [log] (choices:'
|
||||
printf "%s\n" ' dtrace/ftrace/log/nop/simple/syslog/ust)'
|
||||
printf "%s\n" ' --enable-tsan enable thread sanitizer'
|
||||
printf "%s\n" ' --firmwarepath=VALUES search PATH for firmware files [share/qemu-'
|
||||
printf "%s\n" ' firmware]'
|
||||
printf "%s\n" ' --iasl=VALUE Path to ACPI disassembler'
|
||||
@ -57,11 +62,11 @@ meson_options_help() {
|
||||
printf "%s\n" ' --localedir=VALUE Locale data directory [share/locale]'
|
||||
printf "%s\n" ' --localstatedir=VALUE Localstate data directory [/var/local]'
|
||||
printf "%s\n" ' --mandir=VALUE Manual page directory [share/man]'
|
||||
printf "%s\n" ' --sphinx-build=VALUE Use specified sphinx-build for building document'
|
||||
printf "%s\n" ' [sphinx-build]'
|
||||
printf "%s\n" ' --sysconfdir=VALUE Sysconf data directory [etc]'
|
||||
printf "%s\n" ' --tls-priority=VALUE Default TLS protocol/cipher priority string'
|
||||
printf "%s\n" ' [NORMAL]'
|
||||
printf "%s\n" ' --with-coroutine=CHOICE coroutine backend to use (choices:'
|
||||
printf "%s\n" ' auto/sigaltstack/ucontext/windows)'
|
||||
printf "%s\n" ' --with-pkgversion=VALUE use specified string as sub-version of the'
|
||||
printf "%s\n" ' package'
|
||||
printf "%s\n" ' --with-trace-file=VALUE Trace file prefix for simple backend [trace]'
|
||||
@ -129,6 +134,7 @@ meson_options_help() {
|
||||
printf "%s\n" ' lzo lzo compression support'
|
||||
printf "%s\n" ' malloc-trim enable libc malloc_trim() for memory optimization'
|
||||
printf "%s\n" ' membarrier membarrier system call (for Linux 4.14+ or Windows'
|
||||
printf "%s\n" ' modules modules support (non Windows)'
|
||||
printf "%s\n" ' mpath Multipath persistent reservation passthrough'
|
||||
printf "%s\n" ' multiprocess Out of process device emulation support'
|
||||
printf "%s\n" ' netmap netmap network backend support'
|
||||
@ -160,6 +166,7 @@ meson_options_help() {
|
||||
printf "%s\n" ' sparse sparse checker'
|
||||
printf "%s\n" ' spice Spice server support'
|
||||
printf "%s\n" ' spice-protocol Spice protocol support'
|
||||
printf "%s\n" ' stack-protector compiler-provided stack protection'
|
||||
printf "%s\n" ' tcg TCG support'
|
||||
printf "%s\n" ' tools build support utilities that come with QEMU'
|
||||
printf "%s\n" ' tpm TPM support'
|
||||
@ -247,6 +254,7 @@ _meson_option_parse() {
|
||||
--disable-cocoa) printf "%s" -Dcocoa=disabled ;;
|
||||
--enable-coreaudio) printf "%s" -Dcoreaudio=enabled ;;
|
||||
--disable-coreaudio) printf "%s" -Dcoreaudio=disabled ;;
|
||||
--with-coroutine=*) quote_sh "-Dcoroutine_backend=$2" ;;
|
||||
--enable-coroutine-pool) printf "%s" -Dcoroutine_pool=true ;;
|
||||
--disable-coroutine-pool) printf "%s" -Dcoroutine_pool=false ;;
|
||||
--enable-crypto-afalg) printf "%s" -Dcrypto_afalg=enabled ;;
|
||||
@ -258,6 +266,8 @@ _meson_option_parse() {
|
||||
--datadir=*) quote_sh "-Ddatadir=$2" ;;
|
||||
--enable-dbus-display) printf "%s" -Ddbus_display=enabled ;;
|
||||
--disable-dbus-display) printf "%s" -Ddbus_display=disabled ;;
|
||||
--enable-debug-info) printf "%s" -Ddebug=true ;;
|
||||
--disable-debug-info) printf "%s" -Ddebug=false ;;
|
||||
--enable-debug-graph-lock) printf "%s" -Ddebug_graph_lock=true ;;
|
||||
--disable-debug-graph-lock) printf "%s" -Ddebug_graph_lock=false ;;
|
||||
--enable-debug-mutex) printf "%s" -Ddebug_mutex=true ;;
|
||||
@ -361,6 +371,8 @@ _meson_option_parse() {
|
||||
--disable-membarrier) printf "%s" -Dmembarrier=disabled ;;
|
||||
--enable-module-upgrades) printf "%s" -Dmodule_upgrades=true ;;
|
||||
--disable-module-upgrades) printf "%s" -Dmodule_upgrades=false ;;
|
||||
--enable-modules) printf "%s" -Dmodules=enabled ;;
|
||||
--disable-modules) printf "%s" -Dmodules=disabled ;;
|
||||
--enable-mpath) printf "%s" -Dmpath=enabled ;;
|
||||
--disable-mpath) printf "%s" -Dmpath=disabled ;;
|
||||
--enable-multiprocess) printf "%s" -Dmultiprocess=enabled ;;
|
||||
@ -407,6 +419,10 @@ _meson_option_parse() {
|
||||
--disable-replication) printf "%s" -Dreplication=disabled ;;
|
||||
--enable-rng-none) printf "%s" -Drng_none=true ;;
|
||||
--disable-rng-none) printf "%s" -Drng_none=false ;;
|
||||
--enable-safe-stack) printf "%s" -Dsafe_stack=true ;;
|
||||
--disable-safe-stack) printf "%s" -Dsafe_stack=false ;;
|
||||
--enable-sanitizers) printf "%s" -Dsanitizers=true ;;
|
||||
--disable-sanitizers) printf "%s" -Dsanitizers=false ;;
|
||||
--enable-sdl) printf "%s" -Dsdl=enabled ;;
|
||||
--disable-sdl) printf "%s" -Dsdl=disabled ;;
|
||||
--enable-sdl-image) printf "%s" -Dsdl_image=enabled ;;
|
||||
@ -427,11 +443,12 @@ _meson_option_parse() {
|
||||
--disable-sndio) printf "%s" -Dsndio=disabled ;;
|
||||
--enable-sparse) printf "%s" -Dsparse=enabled ;;
|
||||
--disable-sparse) printf "%s" -Dsparse=disabled ;;
|
||||
--sphinx-build=*) quote_sh "-Dsphinx_build=$2" ;;
|
||||
--enable-spice) printf "%s" -Dspice=enabled ;;
|
||||
--disable-spice) printf "%s" -Dspice=disabled ;;
|
||||
--enable-spice-protocol) printf "%s" -Dspice_protocol=enabled ;;
|
||||
--disable-spice-protocol) printf "%s" -Dspice_protocol=disabled ;;
|
||||
--enable-stack-protector) printf "%s" -Dstack_protector=enabled ;;
|
||||
--disable-stack-protector) printf "%s" -Dstack_protector=disabled ;;
|
||||
--enable-strip) printf "%s" -Dstrip=true ;;
|
||||
--disable-strip) printf "%s" -Dstrip=false ;;
|
||||
--sysconfdir=*) quote_sh "-Dsysconfdir=$2" ;;
|
||||
@ -446,6 +463,8 @@ _meson_option_parse() {
|
||||
--disable-tpm) printf "%s" -Dtpm=disabled ;;
|
||||
--enable-trace-backends=*) quote_sh "-Dtrace_backends=$2" ;;
|
||||
--with-trace-file=*) quote_sh "-Dtrace_file=$2" ;;
|
||||
--enable-tsan) printf "%s" -Dtsan=true ;;
|
||||
--disable-tsan) printf "%s" -Dtsan=false ;;
|
||||
--enable-u2f) printf "%s" -Du2f=enabled ;;
|
||||
--disable-u2f) printf "%s" -Du2f=disabled ;;
|
||||
--enable-usb-redir) printf "%s" -Dusb_redir=enabled ;;
|
||||
|
@ -1,7 +1,7 @@
|
||||
[mypy]
|
||||
strict = True
|
||||
disallow_untyped_calls = False
|
||||
python_version = 3.6
|
||||
python_version = 3.7
|
||||
|
||||
[mypy-qapi.schema]
|
||||
disallow_untyped_defs = False
|
||||
|
@ -2253,7 +2253,7 @@ void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr,
|
||||
* If memory region `mr' is NULL, do global sync. Otherwise, sync
|
||||
* dirty bitmap for the specified memory region.
|
||||
*/
|
||||
static void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
|
||||
static void memory_region_sync_dirty_bitmap(MemoryRegion *mr, bool last_stage)
|
||||
{
|
||||
MemoryListener *listener;
|
||||
AddressSpace *as;
|
||||
@ -2283,7 +2283,7 @@ static void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
|
||||
* is to do a global sync, because we are not capable to
|
||||
* sync in a finer granularity.
|
||||
*/
|
||||
listener->log_sync_global(listener);
|
||||
listener->log_sync_global(listener, last_stage);
|
||||
trace_memory_region_sync_dirty(mr ? mr->name : "(all)", listener->name, 1);
|
||||
}
|
||||
}
|
||||
@ -2347,7 +2347,7 @@ DirtyBitmapSnapshot *memory_region_snapshot_and_clear_dirty(MemoryRegion *mr,
|
||||
{
|
||||
DirtyBitmapSnapshot *snapshot;
|
||||
assert(mr->ram_block);
|
||||
memory_region_sync_dirty_bitmap(mr);
|
||||
memory_region_sync_dirty_bitmap(mr, false);
|
||||
snapshot = cpu_physical_memory_snapshot_and_clear_dirty(mr, addr, size, client);
|
||||
memory_global_after_dirty_log_sync();
|
||||
return snapshot;
|
||||
@ -2873,9 +2873,9 @@ bool memory_region_present(MemoryRegion *container, hwaddr addr)
|
||||
return mr && mr != container;
|
||||
}
|
||||
|
||||
void memory_global_dirty_log_sync(void)
|
||||
void memory_global_dirty_log_sync(bool last_stage)
|
||||
{
|
||||
memory_region_sync_dirty_bitmap(NULL);
|
||||
memory_region_sync_dirty_bitmap(NULL, last_stage);
|
||||
}
|
||||
|
||||
void memory_global_after_dirty_log_sync(void)
|
||||
|
@ -863,7 +863,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
|
||||
"tsx-ldtrk", NULL, NULL /* pconfig */, "arch-lbr",
|
||||
NULL, NULL, "amx-bf16", "avx512-fp16",
|
||||
"amx-tile", "amx-int8", "spec-ctrl", "stibp",
|
||||
NULL, "arch-capabilities", "core-capability", "ssbd",
|
||||
"flush-l1d", "arch-capabilities", "core-capability", "ssbd",
|
||||
},
|
||||
.cpuid = {
|
||||
.eax = 7,
|
||||
@ -1050,7 +1050,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
|
||||
"ssb-no", "mds-no", "pschange-mc-no", "tsx-ctrl",
|
||||
"taa-no", NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, "fb-clear", NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
|
@ -899,6 +899,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
|
||||
#define CPUID_7_0_EDX_SPEC_CTRL (1U << 26)
|
||||
/* Single Thread Indirect Branch Predictors */
|
||||
#define CPUID_7_0_EDX_STIBP (1U << 27)
|
||||
/* Flush L1D cache */
|
||||
#define CPUID_7_0_EDX_FLUSH_L1D (1U << 28)
|
||||
/* Arch Capabilities */
|
||||
#define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)
|
||||
/* Core Capability */
|
||||
@ -1016,6 +1018,7 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
|
||||
#define MSR_ARCH_CAP_PSCHANGE_MC_NO (1U << 6)
|
||||
#define MSR_ARCH_CAP_TSX_CTRL_MSR (1U << 7)
|
||||
#define MSR_ARCH_CAP_TAA_NO (1U << 8)
|
||||
#define MSR_ARCH_CAP_FB_CLEAR (1U << 17)
|
||||
|
||||
#define MSR_CORE_CAP_SPLIT_LOCK_DETECT (1U << 5)
|
||||
|
||||
|
@ -2497,6 +2497,14 @@ void helper_vpermdq_ymm(Reg *d, Reg *v, Reg *s, uint32_t order)
|
||||
d->Q(1) = r1;
|
||||
d->Q(2) = r2;
|
||||
d->Q(3) = r3;
|
||||
if (order & 0x8) {
|
||||
d->Q(0) = 0;
|
||||
d->Q(1) = 0;
|
||||
}
|
||||
if (order & 0x80) {
|
||||
d->Q(2) = 0;
|
||||
d->Q(3) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void helper_vpermq_ymm(Reg *d, Reg *s, uint32_t order)
|
||||
|
@ -237,7 +237,7 @@ static void decode_group14(DisasContext *s, CPUX86State *env, X86OpEntry *entry,
|
||||
static void decode_0F6F(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
|
||||
{
|
||||
static const X86OpEntry opcodes_0F6F[4] = {
|
||||
X86_OP_ENTRY3(MOVDQ, P,q, None,None, Q,q, vex1 mmx), /* movq */
|
||||
X86_OP_ENTRY3(MOVDQ, P,q, None,None, Q,q, vex5 mmx), /* movq */
|
||||
X86_OP_ENTRY3(MOVDQ, V,x, None,None, W,x, vex1), /* movdqa */
|
||||
X86_OP_ENTRY3(MOVDQ, V,x, None,None, W,x, vex4_unal), /* movdqu */
|
||||
{},
|
||||
@ -274,9 +274,9 @@ static void decode_0F78(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
|
||||
{
|
||||
static const X86OpEntry opcodes_0F78[4] = {
|
||||
{},
|
||||
X86_OP_ENTRY3(EXTRQ_i, V,x, None,None, I,w, cpuid(SSE4A)),
|
||||
X86_OP_ENTRY3(EXTRQ_i, V,x, None,None, I,w, cpuid(SSE4A)), /* AMD extension */
|
||||
{},
|
||||
X86_OP_ENTRY3(INSERTQ_i, V,x, U,x, I,w, cpuid(SSE4A)),
|
||||
X86_OP_ENTRY3(INSERTQ_i, V,x, U,x, I,w, cpuid(SSE4A)), /* AMD extension */
|
||||
};
|
||||
*entry = *decode_by_prefix(s, opcodes_0F78);
|
||||
}
|
||||
@ -284,9 +284,9 @@ static void decode_0F78(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
|
||||
static void decode_0F79(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
|
||||
{
|
||||
if (s->prefix & PREFIX_REPNZ) {
|
||||
entry->gen = gen_INSERTQ_r;
|
||||
entry->gen = gen_INSERTQ_r; /* AMD extension */
|
||||
} else if (s->prefix & PREFIX_DATA) {
|
||||
entry->gen = gen_EXTRQ_r;
|
||||
entry->gen = gen_EXTRQ_r; /* AMD extension */
|
||||
} else {
|
||||
entry->gen = NULL;
|
||||
};
|
||||
@ -306,7 +306,7 @@ static void decode_0F7E(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
|
||||
static void decode_0F7F(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
|
||||
{
|
||||
static const X86OpEntry opcodes_0F7F[4] = {
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex1 mmx), /* movq */
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex5 mmx), /* movq */
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex1), /* movdqa */
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4_unal), /* movdqu */
|
||||
{},
|
||||
@ -639,15 +639,15 @@ static void decode_0F10(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
|
||||
static const X86OpEntry opcodes_0F10_reg[4] = {
|
||||
X86_OP_ENTRY3(MOVDQ, V,x, None,None, W,x, vex4_unal), /* MOVUPS */
|
||||
X86_OP_ENTRY3(MOVDQ, V,x, None,None, W,x, vex4_unal), /* MOVUPD */
|
||||
X86_OP_ENTRY3(VMOVSS, V,x, H,x, W,x, vex4),
|
||||
X86_OP_ENTRY3(VMOVLPx, V,x, H,x, W,x, vex4), /* MOVSD */
|
||||
X86_OP_ENTRY3(VMOVSS, V,x, H,x, W,x, vex5),
|
||||
X86_OP_ENTRY3(VMOVLPx, V,x, H,x, W,x, vex5), /* MOVSD */
|
||||
};
|
||||
|
||||
static const X86OpEntry opcodes_0F10_mem[4] = {
|
||||
X86_OP_ENTRY3(MOVDQ, V,x, None,None, W,x, vex4_unal), /* MOVUPS */
|
||||
X86_OP_ENTRY3(MOVDQ, V,x, None,None, W,x, vex4_unal), /* MOVUPD */
|
||||
X86_OP_ENTRY3(VMOVSS_ld, V,x, H,x, M,ss, vex4),
|
||||
X86_OP_ENTRY3(VMOVSD_ld, V,x, H,x, M,sd, vex4),
|
||||
X86_OP_ENTRY3(VMOVSS_ld, V,x, H,x, M,ss, vex5),
|
||||
X86_OP_ENTRY3(VMOVSD_ld, V,x, H,x, M,sd, vex5),
|
||||
};
|
||||
|
||||
if ((get_modrm(s, env) >> 6) == 3) {
|
||||
@ -660,17 +660,17 @@ static void decode_0F10(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
|
||||
static void decode_0F11(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
|
||||
{
|
||||
static const X86OpEntry opcodes_0F11_reg[4] = {
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVPS */
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVPD */
|
||||
X86_OP_ENTRY3(VMOVSS, W,x, H,x, V,x, vex4),
|
||||
X86_OP_ENTRY3(VMOVLPx, W,x, H,x, V,q, vex4), /* MOVSD */
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVUPS */
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVUPD */
|
||||
X86_OP_ENTRY3(VMOVSS, W,x, H,x, V,x, vex5),
|
||||
X86_OP_ENTRY3(VMOVLPx, W,x, H,x, V,q, vex5), /* MOVSD */
|
||||
};
|
||||
|
||||
static const X86OpEntry opcodes_0F11_mem[4] = {
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVPS */
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVPD */
|
||||
X86_OP_ENTRY3(VMOVSS_st, M,ss, None,None, V,x, vex4),
|
||||
X86_OP_ENTRY3(VMOVLPx_st, M,sd, None,None, V,x, vex4), /* MOVSD */
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVUPS */
|
||||
X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVUPD */
|
||||
X86_OP_ENTRY3(VMOVSS_st, M,ss, None,None, V,x, vex5),
|
||||
X86_OP_ENTRY3(VMOVLPx_st, M,sd, None,None, V,x, vex5), /* MOVSD */
|
||||
};
|
||||
|
||||
if ((get_modrm(s, env) >> 6) == 3) {
|
||||
@ -687,16 +687,16 @@ static void decode_0F12(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
|
||||
* Use dq for operand for compatibility with gen_MOVSD and
|
||||
* to allow VEX128 only.
|
||||
*/
|
||||
X86_OP_ENTRY3(VMOVLPx_ld, V,dq, H,dq, M,q, vex4), /* MOVLPS */
|
||||
X86_OP_ENTRY3(VMOVLPx_ld, V,dq, H,dq, M,q, vex4), /* MOVLPD */
|
||||
X86_OP_ENTRY3(VMOVLPx_ld, V,dq, H,dq, M,q, vex5), /* MOVLPS */
|
||||
X86_OP_ENTRY3(VMOVLPx_ld, V,dq, H,dq, M,q, vex5), /* MOVLPD */
|
||||
X86_OP_ENTRY3(VMOVSLDUP, V,x, None,None, W,x, vex4 cpuid(SSE3)),
|
||||
X86_OP_ENTRY3(VMOVDDUP, V,x, None,None, WM,q, vex4 cpuid(SSE3)), /* qq if VEX.256 */
|
||||
X86_OP_ENTRY3(VMOVDDUP, V,x, None,None, WM,q, vex5 cpuid(SSE3)), /* qq if VEX.256 */
|
||||
};
|
||||
static const X86OpEntry opcodes_0F12_reg[4] = {
|
||||
X86_OP_ENTRY3(VMOVHLPS, V,dq, H,dq, U,dq, vex4),
|
||||
X86_OP_ENTRY3(VMOVLPx, W,x, H,x, U,q, vex4), /* MOVLPD */
|
||||
X86_OP_ENTRY3(VMOVHLPS, V,dq, H,dq, U,dq, vex7),
|
||||
X86_OP_ENTRY3(VMOVLPx, W,x, H,x, U,q, vex5), /* MOVLPD */
|
||||
X86_OP_ENTRY3(VMOVSLDUP, V,x, None,None, U,x, vex4 cpuid(SSE3)),
|
||||
X86_OP_ENTRY3(VMOVDDUP, V,x, None,None, U,x, vex4 cpuid(SSE3)),
|
||||
X86_OP_ENTRY3(VMOVDDUP, V,x, None,None, U,x, vex5 cpuid(SSE3)),
|
||||
};
|
||||
|
||||
if ((get_modrm(s, env) >> 6) == 3) {
|
||||
@ -716,15 +716,15 @@ static void decode_0F16(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
|
||||
* Operand 1 technically only reads the low 64 bits, but uses dq so that
|
||||
* it is easier to check for op0 == op1 in an endianness-neutral manner.
|
||||
*/
|
||||
X86_OP_ENTRY3(VMOVHPx_ld, V,dq, H,dq, M,q, vex4), /* MOVHPS */
|
||||
X86_OP_ENTRY3(VMOVHPx_ld, V,dq, H,dq, M,q, vex4), /* MOVHPD */
|
||||
X86_OP_ENTRY3(VMOVHPx_ld, V,dq, H,dq, M,q, vex5), /* MOVHPS */
|
||||
X86_OP_ENTRY3(VMOVHPx_ld, V,dq, H,dq, M,q, vex5), /* MOVHPD */
|
||||
X86_OP_ENTRY3(VMOVSHDUP, V,x, None,None, W,x, vex4 cpuid(SSE3)),
|
||||
{},
|
||||
};
|
||||
static const X86OpEntry opcodes_0F16_reg[4] = {
|
||||
/* Same as above, operand 1 could be Hq if it wasn't for big-endian. */
|
||||
X86_OP_ENTRY3(VMOVLHPS, V,dq, H,dq, U,q, vex4),
|
||||
X86_OP_ENTRY3(VMOVHPx, V,x, H,x, U,x, vex4), /* MOVHPD */
|
||||
X86_OP_ENTRY3(VMOVLHPS, V,dq, H,dq, U,q, vex7),
|
||||
X86_OP_ENTRY3(VMOVHPx, V,x, H,x, U,x, vex5), /* MOVHPD */
|
||||
X86_OP_ENTRY3(VMOVSHDUP, V,x, None,None, U,x, vex4 cpuid(SSE3)),
|
||||
{},
|
||||
};
|
||||
@ -750,8 +750,9 @@ static void decode_0F2A(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
|
||||
static void decode_0F2B(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
|
||||
{
|
||||
static const X86OpEntry opcodes_0F2B[4] = {
|
||||
X86_OP_ENTRY3(MOVDQ, M,x, None,None, V,x, vex4), /* MOVNTPS */
|
||||
X86_OP_ENTRY3(MOVDQ, M,x, None,None, V,x, vex4), /* MOVNTPD */
|
||||
X86_OP_ENTRY3(MOVDQ, M,x, None,None, V,x, vex1), /* MOVNTPS */
|
||||
X86_OP_ENTRY3(MOVDQ, M,x, None,None, V,x, vex1), /* MOVNTPD */
|
||||
/* AMD extensions */
|
||||
X86_OP_ENTRY3(VMOVSS_st, M,ss, None,None, V,x, vex4 cpuid(SSE4A)), /* MOVNTSS */
|
||||
X86_OP_ENTRY3(VMOVLPx_st, M,sd, None,None, V,x, vex4 cpuid(SSE4A)), /* MOVNTSD */
|
||||
};
|
||||
@ -783,6 +784,17 @@ static void decode_0F2D(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
|
||||
*entry = *decode_by_prefix(s, opcodes_0F2D);
|
||||
}
|
||||
|
||||
static void decode_VxCOMISx(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
|
||||
{
|
||||
/*
|
||||
* VUCOMISx and VCOMISx are different and use no-prefix and 0x66 for SS and SD
|
||||
* respectively. Scalar values usually are associated with 0xF2 and 0xF3, for
|
||||
* which X86_VEX_REPScalar exists, but here it has to be decoded by hand.
|
||||
*/
|
||||
entry->s1 = entry->s2 = (s->prefix & PREFIX_DATA ? X86_SIZE_sd : X86_SIZE_ss);
|
||||
entry->gen = (*b == 0x2E ? gen_VUCOMI : gen_VCOMI);
|
||||
}
|
||||
|
||||
static void decode_sse_unary(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
|
||||
{
|
||||
if (!(s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))) {
|
||||
@ -813,7 +825,7 @@ static void decode_0FE6(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui
|
||||
static const X86OpEntry opcodes_0FE6[4] = {
|
||||
{},
|
||||
X86_OP_ENTRY2(VCVTTPD2DQ, V,x, W,x, vex2),
|
||||
X86_OP_ENTRY2(VCVTDQ2PD, V,x, W,x, vex2),
|
||||
X86_OP_ENTRY2(VCVTDQ2PD, V,x, W,x, vex5),
|
||||
X86_OP_ENTRY2(VCVTPD2DQ, V,x, W,x, vex2),
|
||||
};
|
||||
*entry = *decode_by_prefix(s, opcodes_0FE6);
|
||||
@ -831,17 +843,17 @@ static const X86OpEntry opcodes_0F[256] = {
|
||||
[0x10] = X86_OP_GROUP0(0F10),
|
||||
[0x11] = X86_OP_GROUP0(0F11),
|
||||
[0x12] = X86_OP_GROUP0(0F12),
|
||||
[0x13] = X86_OP_ENTRY3(VMOVLPx_st, M,q, None,None, V,q, vex4 p_00_66),
|
||||
[0x13] = X86_OP_ENTRY3(VMOVLPx_st, M,q, None,None, V,q, vex5 p_00_66),
|
||||
[0x14] = X86_OP_ENTRY3(VUNPCKLPx, V,x, H,x, W,x, vex4 p_00_66),
|
||||
[0x15] = X86_OP_ENTRY3(VUNPCKHPx, V,x, H,x, W,x, vex4 p_00_66),
|
||||
[0x16] = X86_OP_GROUP0(0F16),
|
||||
/* Incorrectly listed as Mq,Vq in the manual */
|
||||
[0x17] = X86_OP_ENTRY3(VMOVHPx_st, M,q, None,None, V,dq, vex4 p_00_66),
|
||||
[0x17] = X86_OP_ENTRY3(VMOVHPx_st, M,q, None,None, V,dq, vex5 p_00_66),
|
||||
|
||||
[0x50] = X86_OP_ENTRY3(MOVMSK, G,y, None,None, U,x, vex7 p_00_66),
|
||||
[0x51] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
|
||||
[0x52] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex4_rep5 p_00_f3),
|
||||
[0x53] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex4_rep5 p_00_f3),
|
||||
[0x51] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2), /* sqrtps */
|
||||
[0x52] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex4_rep5 p_00_f3), /* rsqrtps */
|
||||
[0x53] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex4_rep5 p_00_f3), /* rcpps */
|
||||
[0x54] = X86_OP_ENTRY3(PAND, V,x, H,x, W,x, vex4 p_00_66), /* vand */
|
||||
[0x55] = X86_OP_ENTRY3(PANDN, V,x, H,x, W,x, vex4 p_00_66), /* vandn */
|
||||
[0x56] = X86_OP_ENTRY3(POR, V,x, H,x, W,x, vex4 p_00_66), /* vor */
|
||||
@ -871,15 +883,15 @@ static const X86OpEntry opcodes_0F[256] = {
|
||||
[0x2B] = X86_OP_GROUP0(0F2B),
|
||||
[0x2C] = X86_OP_GROUP0(0F2C),
|
||||
[0x2D] = X86_OP_GROUP0(0F2D),
|
||||
[0x2E] = X86_OP_ENTRY3(VUCOMI, None,None, V,x, W,x, vex4 p_00_66),
|
||||
[0x2F] = X86_OP_ENTRY3(VCOMI, None,None, V,x, W,x, vex4 p_00_66),
|
||||
[0x2E] = X86_OP_GROUP3(VxCOMISx, None,None, V,x, W,x, vex3 p_00_66), /* VUCOMISS/SD */
|
||||
[0x2F] = X86_OP_GROUP3(VxCOMISx, None,None, V,x, W,x, vex3 p_00_66), /* VCOMISS/SD */
|
||||
|
||||
[0x38] = X86_OP_GROUP0(0F38),
|
||||
[0x3a] = X86_OP_GROUP0(0F3A),
|
||||
|
||||
[0x58] = X86_OP_ENTRY3(VADD, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
|
||||
[0x59] = X86_OP_ENTRY3(VMUL, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
|
||||
[0x5a] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
|
||||
[0x5a] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2), /* CVTPS2PD */
|
||||
[0x5b] = X86_OP_GROUP0(0F5B),
|
||||
[0x5c] = X86_OP_ENTRY3(VSUB, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
|
||||
[0x5d] = X86_OP_ENTRY3(VMIN, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
|
||||
|
@ -2285,7 +2285,7 @@ static void gen_VZEROALL(DisasContext *s, CPUX86State *env, X86DecodedInsn *deco
|
||||
{
|
||||
TCGv_ptr ptr = tcg_temp_new_ptr();
|
||||
|
||||
tcg_gen_addi_ptr(ptr, cpu_env, offsetof(CPUX86State, xmm_t0));
|
||||
tcg_gen_addi_ptr(ptr, cpu_env, offsetof(CPUX86State, xmm_regs));
|
||||
gen_helper_memset(ptr, ptr, tcg_constant_i32(0),
|
||||
tcg_constant_ptr(CPU_NB_REGS * sizeof(ZMMReg)));
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ tcg_ss.add(files(
|
||||
|
||||
if get_option('tcg_interpreter')
|
||||
libffi = dependency('libffi', version: '>=3.0', required: true,
|
||||
method: 'pkg-config', kwargs: static_kwargs)
|
||||
method: 'pkg-config')
|
||||
specific_ss.add(libffi)
|
||||
specific_ss.add(files('tci.c'))
|
||||
endif
|
||||
|
@ -89,7 +89,8 @@ distclean-tcg: $(DISTCLEAN_TCG_TARGET_RULES)
|
||||
# Build up our target list from the filtered list of ninja targets
|
||||
TARGETS=$(patsubst libqemu-%.fa, %, $(filter libqemu-%.fa, $(ninja-targets)))
|
||||
|
||||
TESTS_VENV_DIR=$(BUILD_DIR)/tests/venv
|
||||
TESTS_VENV_DIR=$(BUILD_DIR)/pyvenv
|
||||
TESTS_VENV_TOKEN=$(BUILD_DIR)/pyvenv/tests.group
|
||||
TESTS_VENV_REQ=$(SRC_PATH)/tests/requirements.txt
|
||||
TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
|
||||
TESTS_PYTHON=$(TESTS_VENV_DIR)/bin/python3
|
||||
@ -111,8 +112,7 @@ quiet-venv-pip = $(quiet-@)$(call quiet-command-run, \
|
||||
$(TESTS_PYTHON) -m pip -q --disable-pip-version-check $1, \
|
||||
"VENVPIP","$1")
|
||||
|
||||
$(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
|
||||
$(call quiet-command, $(PYTHON) -m venv $@, VENV, $@)
|
||||
$(TESTS_VENV_TOKEN): $(TESTS_VENV_REQ)
|
||||
$(call quiet-venv-pip,install -e "$(SRC_PATH)/python/")
|
||||
$(call quiet-venv-pip,install -r $(TESTS_VENV_REQ))
|
||||
$(call quiet-command, touch $@)
|
||||
@ -121,7 +121,7 @@ $(TESTS_RESULTS_DIR):
|
||||
$(call quiet-command, mkdir -p $@, \
|
||||
MKDIR, $@)
|
||||
|
||||
check-venv: $(TESTS_VENV_DIR)
|
||||
check-venv: $(TESTS_VENV_TOKEN)
|
||||
|
||||
FEDORA_31_ARCHES_TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGETS)))
|
||||
FEDORA_31_ARCHES_CANDIDATES=$(patsubst ppc64,ppc64le,$(FEDORA_31_ARCHES_TARGETS))
|
||||
@ -167,7 +167,7 @@ check:
|
||||
check-build: run-ninja
|
||||
|
||||
check-clean:
|
||||
rm -rf $(TESTS_VENV_DIR) $(TESTS_RESULTS_DIR)
|
||||
rm -rf $(TESTS_RESULTS_DIR)
|
||||
|
||||
clean: check-clean clean-tcg
|
||||
distclean: distclean-tcg
|
||||
|
@ -57,7 +57,8 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
|
||||
gcc-sh4-linux-gnu \
|
||||
libc6-dev-sh4-cross \
|
||||
gcc-sparc64-linux-gnu \
|
||||
libc6-dev-sparc64-cross
|
||||
libc6-dev-sparc64-cross \
|
||||
python3-venv
|
||||
|
||||
ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
|
||||
ENV DEF_TARGET_LIST aarch64-linux-user,alpha-linux-user,arm-linux-user,hppa-linux-user,i386-linux-user,m68k-linux-user,mips-linux-user,mips64-linux-user,mips64el-linux-user,mipsel-linux-user,ppc-linux-user,ppc64-linux-user,ppc64le-linux-user,riscv64-linux-user,s390x-linux-user,sh4-linux-user,sparc64-linux-user
|
||||
|
@ -20,7 +20,8 @@ RUN apt-get update && \
|
||||
bison \
|
||||
flex \
|
||||
git \
|
||||
ninja-build && \
|
||||
ninja-build \
|
||||
python3-venv && \
|
||||
# Install QEMU build deps for use in CI
|
||||
DEBIAN_FRONTEND=noninteractive eatmydata \
|
||||
apt build-dep -yy --arch-only qemu
|
||||
|
@ -28,7 +28,8 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy \
|
||||
libglib2.0-dev \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
python3
|
||||
python3 \
|
||||
python3-venv
|
||||
|
||||
# Add ports and riscv64 architecture
|
||||
RUN echo "deb http://ftp.ports.debian.org/debian-ports/ sid main" >> /etc/apt/sources.list
|
||||
|
@ -33,7 +33,8 @@ RUN apt update && \
|
||||
pkgconf \
|
||||
python3-pip \
|
||||
python3-setuptools \
|
||||
python3-wheel
|
||||
python3-wheel \
|
||||
python3-venv
|
||||
|
||||
RUN curl -#SL https://github.com/bkoppelmann/package_940/releases/download/tricore-toolchain-9.40/tricore-toolchain-9.4.0.tar.gz \
|
||||
| tar -xzC /usr/local/
|
||||
|
@ -2,7 +2,7 @@ if not have_tools or targetos == 'windows' or get_option('gprof')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
foreach cflag: config_host['QEMU_CFLAGS'].split()
|
||||
foreach cflag: qemu_ldflags
|
||||
if cflag.startswith('-fsanitize') and \
|
||||
not cflag.contains('safe-stack') and not cflag.contains('cfi-icall')
|
||||
message('Sanitizers are enabled ==> Disabled the qemu-iotests.')
|
||||
|
@ -23,7 +23,7 @@ qtests_generic = [
|
||||
'readconfig-test',
|
||||
'netdev-socket',
|
||||
]
|
||||
if config_host.has_key('CONFIG_MODULES')
|
||||
if enable_modules
|
||||
qtests_generic += [ 'modules-test' ]
|
||||
endif
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
# Add Python module requirements, one per line, to be installed
|
||||
# in the tests/venv Python virtual environment. For more info,
|
||||
# in the qemu build_dir/pyvenv Python virtual environment. For more info,
|
||||
# refer to: https://pip.pypa.io/en/stable/user_guide/#id1
|
||||
# Note that qemu.git/python/ is always implicitly installed.
|
||||
#
|
||||
# Note that qemu.git/python/ is implicitly installed to this venv when
|
||||
# 'make check-venv' is run, and will persist until configure is run
|
||||
# again.
|
||||
avocado-framework==101.0
|
||||
pycdlib==1.11.0
|
||||
|
@ -49,7 +49,7 @@ imask = {
|
||||
'VEXTRACT[FI]128': 0x01,
|
||||
'VINSERT[FI]128': 0x01,
|
||||
'VPBLENDD': 0xff,
|
||||
'VPERM2[FI]128': 0x33,
|
||||
'VPERM2[FI]128': 0xbb,
|
||||
'VPERMPD': 0xff,
|
||||
'VPERMQ': 0xff,
|
||||
'VPERMILPS': 0xff,
|
||||
|
@ -147,7 +147,7 @@ if have_system
|
||||
# Some tests: test-char, test-qdev-global-props, and test-qga,
|
||||
# are not runnable under TSan due to a known issue.
|
||||
# https://github.com/google/sanitizers/issues/1116
|
||||
if 'CONFIG_TSAN' not in config_host
|
||||
if not get_option('tsan')
|
||||
if 'CONFIG_POSIX' in config_host
|
||||
tests += {
|
||||
'test-char': ['socket-helpers.c', qom, io, chardev]
|
||||
|
@ -30,6 +30,8 @@ class NetBSDVM(basevm.BaseVM):
|
||||
"git-base",
|
||||
"pkgconf",
|
||||
"xz",
|
||||
"python310",
|
||||
"py310-expat",
|
||||
"ninja-build",
|
||||
|
||||
# gnu tools
|
||||
|
@ -26,7 +26,9 @@ util_ss.add(when: 'CONFIG_WIN32', if_true: files('oslib-win32.c'))
|
||||
util_ss.add(when: 'CONFIG_WIN32', if_true: files('qemu-thread-win32.c'))
|
||||
util_ss.add(when: 'CONFIG_WIN32', if_true: winmm)
|
||||
util_ss.add(when: 'CONFIG_WIN32', if_true: pathcch)
|
||||
util_ss.add(when: 'HAVE_GLIB_WITH_SLICE_ALLOCATOR', if_true: files('qtree.c'))
|
||||
if glib_has_gslice
|
||||
util_ss.add(files('qtree.c'))
|
||||
endif
|
||||
util_ss.add(files('envlist.c', 'path.c', 'module.c'))
|
||||
util_ss.add(files('host-utils.c'))
|
||||
util_ss.add(files('bitmap.c', 'bitops.c'))
|
||||
@ -76,7 +78,7 @@ if have_block or have_ga
|
||||
util_ss.add(files('base64.c'))
|
||||
util_ss.add(files('main-loop.c'))
|
||||
util_ss.add(files('qemu-coroutine.c', 'qemu-coroutine-lock.c', 'qemu-coroutine-io.c'))
|
||||
util_ss.add(files('coroutine-@0@.c'.format(config_host['CONFIG_COROUTINE_BACKEND'])))
|
||||
util_ss.add(files(f'coroutine-@coroutine_backend@.c'))
|
||||
util_ss.add(files('thread-pool.c', 'qemu-timer.c'))
|
||||
util_ss.add(files('qemu-sockets.c'))
|
||||
endif
|
||||
|
Loading…
Reference in New Issue
Block a user