testing, gdbstub, plugin and gitdm updates

- cleanup scripts/ci/setup in advance of ppc64 runner
   - ensure detected gdb reported to TCG tests
   - update hexagon container with build deps
   - move alpine container to tagged release
   - fix overflow during qos-test test tree iteration
   - allow bios blobs to be built with test cross compilers
   - introduce monitor_puts for plain strings
   - share disas code between monitor and plugins
   - fix bug in execlog plugin
   - add more tcg plugin documentation, reorg
   - fix link to semihosting spec
   - re-factor gdbstub to use AccelClass/Ops
   - many gitdm updates
   - fix race with plugin mutex lock and linux-user fork()
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmM+s+YACgkQ+9DbCVqe
 KkSDwgf/Qj0OScOr5Bfw3/KAV0/SFL1vHISb2r5qZVG4DvdY/c/sitPBHPJ8N5jQ
 918M8AiI3+4Mb/GwkdYBEyWgVZ5ELOkJTObypa5pwmF1K/xDUlG7ZRmJ9+xkJ44Q
 TmrVLQyw6d907B2u+DfqX68AYYnto1yQT/eUo6TiLdIJ5NXIYRn5u34snG9qWHja
 b/Dp7DxnoJMS1EhlMhukekCHGGNUeYn4ewIKbsG1EouH5PndzrvP8LRAcWyxv0m4
 tD2bEAHCMKqTqefkNgG7GCO3HND1JBfWdckx3OD4hBnMnuNtsZBL23QN7MDytgnv
 0JnYSwkWZCuMIt7oKCOXLUbCjQG97Q==
 =1vZ4
 -----END PGP SIGNATURE-----

Merge tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu into staging

testing, gdbstub, plugin and gitdm updates

  - cleanup scripts/ci/setup in advance of ppc64 runner
  - ensure detected gdb reported to TCG tests
  - update hexagon container with build deps
  - move alpine container to tagged release
  - fix overflow during qos-test test tree iteration
  - allow bios blobs to be built with test cross compilers
  - introduce monitor_puts for plain strings
  - share disas code between monitor and plugins
  - fix bug in execlog plugin
  - add more tcg plugin documentation, reorg
  - fix link to semihosting spec
  - re-factor gdbstub to use AccelClass/Ops
  - many gitdm updates
  - fix race with plugin mutex lock and linux-user fork()

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmM+s+YACgkQ+9DbCVqe
# KkSDwgf/Qj0OScOr5Bfw3/KAV0/SFL1vHISb2r5qZVG4DvdY/c/sitPBHPJ8N5jQ
# 918M8AiI3+4Mb/GwkdYBEyWgVZ5ELOkJTObypa5pwmF1K/xDUlG7ZRmJ9+xkJ44Q
# TmrVLQyw6d907B2u+DfqX68AYYnto1yQT/eUo6TiLdIJ5NXIYRn5u34snG9qWHja
# b/Dp7DxnoJMS1EhlMhukekCHGGNUeYn4ewIKbsG1EouH5PndzrvP8LRAcWyxv0m4
# tD2bEAHCMKqTqefkNgG7GCO3HND1JBfWdckx3OD4hBnMnuNtsZBL23QN7MDytgnv
# 0JnYSwkWZCuMIt7oKCOXLUbCjQG97Q==
# =1vZ4
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 06 Oct 2022 06:54:30 EDT
# gpg:                using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [unknown]
# 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: 6685 AE99 E751 67BC AFC8  DF35 FBD0 DB09 5A9E 2A44

* tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu: (52 commits)
  plugins: add [pre|post]fork helpers to linux-user
  contrib/gitdm: add Université Grenoble Alpes
  contrib/gitdm: add Simon to individual contributors
  contrib/gitdm: add China Telecom to the domain map
  contrib/gitdm: add ISCAS to the academics group
  contrib/gitdm: add WANG Xuerui to individual contributers
  contrib/gitdm: add Paul to individual contributors
  contrib/gitdm: add mapping for Loongson Technology
  accel/kvm: move kvm_update_guest_debug to inline stub
  gdbstub: move guest debug support check to ops
  gdbstub: move breakpoint logic to accel ops
  gdbstub: move sstep flags probing into AccelClass
  gdbstub: move into its own sub directory
  semihosting: update link to spec
  docs/devel: document the test plugins
  contrib/plugins: reset skip when matching in execlog
  docs/devel: move API to end of tcg-plugins.rst
  docs/devel: clean-up qemu invocations in tcg-plugins
  plugins: Assert mmu_idx in range before use in qemu_plugin_get_hwaddr
  plugins: extend execlog to filter matches
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
master
Stefan Hajnoczi 2022-10-06 07:11:56 -04:00
commit f1d33f55c4
98 changed files with 1136 additions and 622 deletions

View File

@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
NINJA='/usr/local/bin/ninja' NINJA='/usr/local/bin/ninja'
PACKAGING_COMMAND='pkg' PACKAGING_COMMAND='pkg'
PIP3='/usr/local/bin/pip-3.8' PIP3='/usr/local/bin/pip-3.8'
PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
PYPI_PKGS='' PYPI_PKGS=''
PYTHON='/usr/local/bin/python3' PYTHON='/usr/local/bin/python3'

View File

@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
NINJA='/usr/local/bin/ninja' NINJA='/usr/local/bin/ninja'
PACKAGING_COMMAND='pkg' PACKAGING_COMMAND='pkg'
PIP3='/usr/local/bin/pip-3.8' PIP3='/usr/local/bin/pip-3.8'
PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
PYPI_PKGS='' PYPI_PKGS=''
PYTHON='/usr/local/bin/python3' PYTHON='/usr/local/bin/python3'

View File

@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
NINJA='/usr/local/bin/ninja' NINJA='/usr/local/bin/ninja'
PACKAGING_COMMAND='brew' PACKAGING_COMMAND='brew'
PIP3='/usr/local/bin/pip3' PIP3='/usr/local/bin/pip3'
PKGS='bash bc bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson ncurses nettle ninja perl pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy sparse spice-protocol tesseract texinfo usbredir vde vte3 zlib zstd' PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson ncurses nettle ninja perl pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy sparse spice-protocol tesseract texinfo usbredir vde vte3 zlib zstd'
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme' PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme'
PYTHON='/usr/local/bin/python3' PYTHON='/usr/local/bin/python3'

View File

@ -33,7 +33,8 @@ msys2-64bit:
extends: .shared_msys2_builder extends: .shared_msys2_builder
script: script:
- .\msys64\usr\bin\bash -lc "pacman -Sy --noconfirm --needed - .\msys64\usr\bin\bash -lc "pacman -Sy --noconfirm --needed
diffutils git grep make sed bison diffutils flex
git grep make sed
mingw-w64-x86_64-capstone mingw-w64-x86_64-capstone
mingw-w64-x86_64-curl mingw-w64-x86_64-curl
mingw-w64-x86_64-cyrus-sasl mingw-w64-x86_64-cyrus-sasl
@ -67,7 +68,8 @@ msys2-32bit:
extends: .shared_msys2_builder extends: .shared_msys2_builder
script: script:
- .\msys64\usr\bin\bash -lc "pacman -Sy --noconfirm --needed - .\msys64\usr\bin\bash -lc "pacman -Sy --noconfirm --needed
diffutils git grep make sed bison diffutils flex
git grep make sed
mingw-w64-i686-capstone mingw-w64-i686-capstone
mingw-w64-i686-curl mingw-w64-i686-curl
mingw-w64-i686-cyrus-sasl mingw-w64-i686-cyrus-sasl

View File

@ -65,6 +65,7 @@ James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org> Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com> Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
Radoslaw Biernacki <rad@semihalf.com> <radoslaw.biernacki@linaro.org> Radoslaw Biernacki <rad@semihalf.com> <radoslaw.biernacki@linaro.org>
Paul Brook <paul@nowt.org> <paul@codesourcery.com>
Paul Burton <paulburton@kernel.org> <paul.burton@mips.com> Paul Burton <paulburton@kernel.org> <paul.burton@mips.com>
Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com> Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com>
Paul Burton <paulburton@kernel.org> <paul@archlinuxmips.org> Paul Burton <paulburton@kernel.org> <paul@archlinuxmips.org>

View File

@ -2677,7 +2677,7 @@ GDB stub
M: Alex Bennée <alex.bennee@linaro.org> M: Alex Bennée <alex.bennee@linaro.org>
R: Philippe Mathieu-Daudé <f4bug@amsat.org> R: Philippe Mathieu-Daudé <f4bug@amsat.org>
S: Maintained S: Maintained
F: gdbstub* F: gdbstub/*
F: include/exec/gdbstub.h F: include/exec/gdbstub.h
F: gdb-xml/ F: gdb-xml/
F: tests/tcg/multiarch/gdbstub/ F: tests/tcg/multiarch/gdbstub/

View File

@ -42,6 +42,9 @@ configure: ;
ifneq ($(wildcard config-host.mak),) ifneq ($(wildcard config-host.mak),)
include config-host.mak include config-host.mak
include Makefile.prereqs
Makefile.prereqs: config-host.mak
git-submodule-update: git-submodule-update:
.git-submodule-status: git-submodule-update config-host.mak .git-submodule-status: git-submodule-update config-host.mak
Makefile: .git-submodule-status Makefile: .git-submodule-status
@ -186,7 +189,7 @@ include $(SRC_PATH)/tests/Makefile.include
all: recurse-all all: recurse-all
ROMS_RULES=$(foreach t, all clean, $(addsuffix /$(t), $(ROMS))) ROMS_RULES=$(foreach t, all clean distclean, $(addsuffix /$(t), $(ROMS)))
.PHONY: $(ROMS_RULES) .PHONY: $(ROMS_RULES)
$(ROMS_RULES): $(ROMS_RULES):
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) V="$(V)" TARGET_DIR="$(dir $@)" $(notdir $@),) $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) V="$(V)" TARGET_DIR="$(dir $@)" $(notdir $@),)
@ -194,6 +197,7 @@ $(ROMS_RULES):
.PHONY: recurse-all recurse-clean .PHONY: recurse-all recurse-clean
recurse-all: $(addsuffix /all, $(ROMS)) recurse-all: $(addsuffix /all, $(ROMS))
recurse-clean: $(addsuffix /clean, $(ROMS)) recurse-clean: $(addsuffix /clean, $(ROMS))
recurse-distclean: $(addsuffix /distclean, $(ROMS))
###################################################################### ######################################################################
@ -214,10 +218,10 @@ dist: qemu-$(VERSION).tar.bz2
qemu-%.tar.bz2: qemu-%.tar.bz2:
$(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.bz2,%,$@)" $(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.bz2,%,$@)"
distclean: clean distclean: clean recurse-distclean
-$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean -g || : -$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean -g || :
rm -f config-host.mak qemu-bundle rm -f config-host.mak Makefile.prereqs qemu-bundle
rm -f tests/tcg/config-*.mak rm -f tests/tcg/*/config-target.mak tests/tcg/config-host.mak
rm -f config.status rm -f config.status
rm -f roms/seabios/config.mak rm -f roms/seabios/config.mak
rm -f qemu-plugins-ld.symbols qemu-plugins-ld64.symbols rm -f qemu-plugins-ld.symbols qemu-plugins-ld64.symbols

View File

@ -129,6 +129,16 @@ bool accel_cpu_realizefn(CPUState *cpu, Error **errp)
return true; return true;
} }
int accel_supported_gdbstub_sstep_flags(void)
{
AccelState *accel = current_accel();
AccelClass *acc = ACCEL_GET_CLASS(accel);
if (acc->gdbstub_supported_sstep_flags) {
return acc->gdbstub_supported_sstep_flags();
}
return 0;
}
static const TypeInfo accel_cpu_type = { static const TypeInfo accel_cpu_type = {
.name = TYPE_ACCEL_CPU, .name = TYPE_ACCEL_CPU,
.parent = TYPE_OBJECT, .parent = TYPE_OBJECT,

View File

@ -16,12 +16,14 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
#include "sysemu/kvm.h"
#include "sysemu/kvm_int.h" #include "sysemu/kvm_int.h"
#include "sysemu/runstate.h" #include "sysemu/runstate.h"
#include "sysemu/cpus.h" #include "sysemu/cpus.h"
#include "qemu/guest-random.h" #include "qemu/guest-random.h"
#include "qapi/error.h" #include "qapi/error.h"
#include <linux/kvm.h>
#include "kvm-cpus.h" #include "kvm-cpus.h"
static void *kvm_vcpu_thread_fn(void *arg) static void *kvm_vcpu_thread_fn(void *arg)
@ -95,6 +97,13 @@ static void kvm_accel_ops_class_init(ObjectClass *oc, void *data)
ops->synchronize_post_init = kvm_cpu_synchronize_post_init; ops->synchronize_post_init = kvm_cpu_synchronize_post_init;
ops->synchronize_state = kvm_cpu_synchronize_state; ops->synchronize_state = kvm_cpu_synchronize_state;
ops->synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm; ops->synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm;
#ifdef KVM_CAP_SET_GUEST_DEBUG
ops->supports_guest_debug = kvm_supports_guest_debug;
ops->insert_breakpoint = kvm_insert_breakpoint;
ops->remove_breakpoint = kvm_remove_breakpoint;
ops->remove_all_breakpoints = kvm_remove_all_breakpoints;
#endif
} }
static const TypeInfo kvm_accel_ops_type = { static const TypeInfo kvm_accel_ops_type = {

View File

@ -175,7 +175,7 @@ bool kvm_direct_msi_allowed;
bool kvm_ioeventfd_any_length_allowed; bool kvm_ioeventfd_any_length_allowed;
bool kvm_msi_use_devid; bool kvm_msi_use_devid;
bool kvm_has_guest_debug; bool kvm_has_guest_debug;
int kvm_sstep_flags; static int kvm_sstep_flags;
static bool kvm_immediate_exit; static bool kvm_immediate_exit;
static hwaddr kvm_max_slot_size = ~0; static hwaddr kvm_max_slot_size = ~0;
@ -3287,8 +3287,13 @@ int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap)
return data.err; return data.err;
} }
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, bool kvm_supports_guest_debug(void)
target_ulong len, int type) {
/* probed during kvm_init() */
return kvm_has_guest_debug;
}
int kvm_insert_breakpoint(CPUState *cpu, int type, hwaddr addr, hwaddr len)
{ {
struct kvm_sw_breakpoint *bp; struct kvm_sw_breakpoint *bp;
int err; int err;
@ -3326,8 +3331,7 @@ int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
return 0; return 0;
} }
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, int kvm_remove_breakpoint(CPUState *cpu, int type, hwaddr addr, hwaddr len)
target_ulong len, int type)
{ {
struct kvm_sw_breakpoint *bp; struct kvm_sw_breakpoint *bp;
int err; int err;
@ -3391,28 +3395,6 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
} }
} }
#else /* !KVM_CAP_SET_GUEST_DEBUG */
int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap)
{
return -EINVAL;
}
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
target_ulong len, int type)
{
return -EINVAL;
}
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
target_ulong len, int type)
{
return -EINVAL;
}
void kvm_remove_all_breakpoints(CPUState *cpu)
{
}
#endif /* !KVM_CAP_SET_GUEST_DEBUG */ #endif /* !KVM_CAP_SET_GUEST_DEBUG */
static int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset) static int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
@ -3712,6 +3694,17 @@ static void kvm_accel_instance_init(Object *obj)
s->kvm_dirty_ring_size = 0; s->kvm_dirty_ring_size = 0;
} }
/**
* kvm_gdbstub_sstep_flags():
*
* Returns: SSTEP_* flags that KVM supports for guest debug. The
* support is probed during kvm_init()
*/
static int kvm_gdbstub_sstep_flags(void)
{
return kvm_sstep_flags;
}
static void kvm_accel_class_init(ObjectClass *oc, void *data) static void kvm_accel_class_init(ObjectClass *oc, void *data)
{ {
AccelClass *ac = ACCEL_CLASS(oc); AccelClass *ac = ACCEL_CLASS(oc);
@ -3719,6 +3712,7 @@ static void kvm_accel_class_init(ObjectClass *oc, void *data)
ac->init_machine = kvm_init; ac->init_machine = kvm_init;
ac->has_memory = kvm_accel_has_memory; ac->has_memory = kvm_accel_has_memory;
ac->allowed = &kvm_allowed; ac->allowed = &kvm_allowed;
ac->gdbstub_supported_sstep_flags = kvm_gdbstub_sstep_flags;
object_class_property_add(oc, "kernel-irqchip", "on|off|split", object_class_property_add(oc, "kernel-irqchip", "on|off|split",
NULL, kvm_set_kernel_irqchip, NULL, kvm_set_kernel_irqchip,

View File

@ -18,5 +18,9 @@ void kvm_destroy_vcpu(CPUState *cpu);
void kvm_cpu_synchronize_post_reset(CPUState *cpu); void kvm_cpu_synchronize_post_reset(CPUState *cpu);
void kvm_cpu_synchronize_post_init(CPUState *cpu); void kvm_cpu_synchronize_post_init(CPUState *cpu);
void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu); void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu);
bool kvm_supports_guest_debug(void);
int kvm_insert_breakpoint(CPUState *cpu, int type, hwaddr addr, hwaddr len);
int kvm_remove_breakpoint(CPUState *cpu, int type, hwaddr addr, hwaddr len);
void kvm_remove_all_breakpoints(CPUState *cpu);
#endif /* KVM_CPUS_H */ #endif /* KVM_CPUS_H */

View File

@ -46,27 +46,6 @@ int kvm_has_many_ioeventfds(void)
return 0; return 0;
} }
int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap)
{
return -ENOSYS;
}
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
target_ulong len, int type)
{
return -EINVAL;
}
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
target_ulong len, int type)
{
return -EINVAL;
}
void kvm_remove_all_breakpoints(CPUState *cpu)
{
}
int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr) int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
{ {
return 1; return 1;

View File

@ -32,6 +32,8 @@
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
#include "qemu/guest-random.h" #include "qemu/guest-random.h"
#include "exec/exec-all.h" #include "exec/exec-all.h"
#include "exec/hwaddr.h"
#include "exec/gdbstub.h"
#include "tcg-accel-ops.h" #include "tcg-accel-ops.h"
#include "tcg-accel-ops-mttcg.h" #include "tcg-accel-ops-mttcg.h"
@ -91,6 +93,97 @@ void tcg_handle_interrupt(CPUState *cpu, int mask)
} }
} }
static bool tcg_supports_guest_debug(void)
{
return true;
}
/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
{
static const int xlat[] = {
[GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
[GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
[GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
};
CPUClass *cc = CPU_GET_CLASS(cpu);
int cputype = xlat[gdbtype];
if (cc->gdb_stop_before_watchpoint) {
cputype |= BP_STOP_BEFORE_ACCESS;
}
return cputype;
}
static int tcg_insert_breakpoint(CPUState *cs, int type, hwaddr addr, hwaddr len)
{
CPUState *cpu;
int err = 0;
switch (type) {
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
CPU_FOREACH(cpu) {
err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
if (err) {
break;
}
}
return err;
case GDB_WATCHPOINT_WRITE:
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
CPU_FOREACH(cpu) {
err = cpu_watchpoint_insert(cpu, addr, len,
xlat_gdb_type(cpu, type), NULL);
if (err) {
break;
}
}
return err;
default:
return -ENOSYS;
}
}
static int tcg_remove_breakpoint(CPUState *cs, int type, hwaddr addr, hwaddr len)
{
CPUState *cpu;
int err = 0;
switch (type) {
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
CPU_FOREACH(cpu) {
err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
if (err) {
break;
}
}
return err;
case GDB_WATCHPOINT_WRITE:
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
CPU_FOREACH(cpu) {
err = cpu_watchpoint_remove(cpu, addr, len,
xlat_gdb_type(cpu, type));
if (err) {
break;
}
}
return err;
default:
return -ENOSYS;
}
}
static inline void tcg_remove_all_breakpoints(CPUState *cpu)
{
cpu_breakpoint_remove_all(cpu, BP_GDB);
cpu_watchpoint_remove_all(cpu, BP_GDB);
}
static void tcg_accel_ops_init(AccelOpsClass *ops) static void tcg_accel_ops_init(AccelOpsClass *ops)
{ {
if (qemu_tcg_mttcg_enabled()) { if (qemu_tcg_mttcg_enabled()) {
@ -109,6 +202,11 @@ static void tcg_accel_ops_init(AccelOpsClass *ops)
ops->handle_interrupt = tcg_handle_interrupt; ops->handle_interrupt = tcg_handle_interrupt;
} }
} }
ops->supports_guest_debug = tcg_supports_guest_debug;
ops->insert_breakpoint = tcg_insert_breakpoint;
ops->remove_breakpoint = tcg_remove_breakpoint;
ops->remove_all_breakpoints = tcg_remove_all_breakpoints;
} }
static void tcg_accel_ops_class_init(ObjectClass *oc, void *data) static void tcg_accel_ops_class_init(ObjectClass *oc, void *data)

View File

@ -25,6 +25,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "sysemu/tcg.h" #include "sysemu/tcg.h"
#include "sysemu/replay.h"
#include "sysemu/cpu-timers.h" #include "sysemu/cpu-timers.h"
#include "tcg/tcg.h" #include "tcg/tcg.h"
#include "qapi/error.h" #include "qapi/error.h"
@ -207,12 +208,28 @@ static void tcg_set_splitwx(Object *obj, bool value, Error **errp)
s->splitwx_enabled = value; s->splitwx_enabled = value;
} }
static int tcg_gdbstub_supported_sstep_flags(void)
{
/*
* In replay mode all events will come from the log and can't be
* suppressed otherwise we would break determinism. However as those
* events are tied to the number of executed instructions we won't see
* them occurring every time we single step.
*/
if (replay_mode != REPLAY_MODE_NONE) {
return SSTEP_ENABLE;
} else {
return SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
}
}
static void tcg_accel_class_init(ObjectClass *oc, void *data) static void tcg_accel_class_init(ObjectClass *oc, void *data)
{ {
AccelClass *ac = ACCEL_CLASS(oc); AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "tcg"; ac->name = "tcg";
ac->init_machine = tcg_init_machine; ac->init_machine = tcg_init_machine;
ac->allowed = &tcg_allowed; ac->allowed = &tcg_allowed;
ac->gdbstub_supported_sstep_flags = tcg_gdbstub_supported_sstep_flags;
object_class_property_add_str(oc, "thread", object_class_property_add_str(oc, "thread",
tcg_get_thread, tcg_get_thread,

View File

@ -638,16 +638,16 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
assert(!info || !info->has_inserted || info->inserted == inserted); assert(!info || !info->has_inserted || info->inserted == inserted);
if (info && *info->device) { if (info && *info->device) {
monitor_printf(mon, "%s", info->device); monitor_puts(mon, info->device);
if (inserted && inserted->has_node_name) { if (inserted && inserted->has_node_name) {
monitor_printf(mon, " (%s)", inserted->node_name); monitor_printf(mon, " (%s)", inserted->node_name);
} }
} else { } else {
assert(info || inserted); assert(info || inserted);
monitor_printf(mon, "%s", monitor_puts(mon,
inserted && inserted->has_node_name ? inserted->node_name inserted && inserted->has_node_name ? inserted->node_name
: info && info->has_qdev ? info->qdev : info && info->has_qdev ? info->qdev
: "<anonymous>"); : "<anonymous>");
} }
if (inserted) { if (inserted) {

238
configure vendored
View File

@ -1779,8 +1779,13 @@ fi
container="no" container="no"
if test $use_containers = "yes"; then if test $use_containers = "yes"; then
if has "docker" || has "podman"; then case $($python "$source_path"/tests/docker/docker.py probe) in
container=$($python "$source_path"/tests/docker/docker.py probe) *docker) container=docker ;;
podman) container=podman ;;
no) container=no ;;
esac
if test "$container" != "no"; then
docker_py="$python $source_path/tests/docker/docker.py --engine $container"
fi fi
fi fi
@ -2116,54 +2121,54 @@ probe_target_compiler() {
target_ranlib= target_ranlib=
target_strip= target_strip=
fi fi
test -n "$target_cc" || test -n "$container_image"
} }
write_target_makefile() { write_target_makefile() {
echo "EXTRA_CFLAGS=$target_cflags" echo "EXTRA_CFLAGS=$target_cflags"
if test -n "$target_cc"; then if test -z "$target_cc" && test -z "$target_as"; then
echo "CC=$target_cc" test -z "$container_image" && error_exit "Internal error: could not find cross compiler for $1?"
echo "CCAS=$target_ccas" echo "$1: docker-image-$container_image" >> Makefile.prereqs
fi if test -n "$container_cross_cc"; then
if test -n "$target_ar"; then echo "CC=$docker_py cc --cc $container_cross_cc -i qemu/$container_image -s $source_path --"
echo "AR=$target_ar" echo "CCAS=$docker_py cc --cc $container_cross_cc -i qemu/$container_image -s $source_path --"
fi fi
if test -n "$target_as"; then echo "AR=$docker_py cc --cc $container_cross_ar -i qemu/$container_image -s $source_path --"
echo "AS=$target_as" echo "AS=$docker_py cc --cc $container_cross_as -i qemu/$container_image -s $source_path --"
fi echo "LD=$docker_py cc --cc $container_cross_ld -i qemu/$container_image -s $source_path --"
if test -n "$target_ld"; then echo "NM=$docker_py cc --cc $container_cross_nm -i qemu/$container_image -s $source_path --"
echo "LD=$target_ld" echo "OBJCOPY=$docker_py cc --cc $container_cross_objcopy -i qemu/$container_image -s $source_path --"
fi echo "RANLIB=$docker_py cc --cc $container_cross_ranlib -i qemu/$container_image -s $source_path --"
if test -n "$target_nm"; then echo "STRIP=$docker_py cc --cc $container_cross_strip -i qemu/$container_image -s $source_path --"
echo "NM=$target_nm" else
fi if test -n "$target_cc"; then
if test -n "$target_objcopy"; then echo "CC=$target_cc"
echo "OBJCOPY=$target_objcopy" echo "CCAS=$target_ccas"
fi fi
if test -n "$target_ranlib"; then if test -n "$target_ar"; then
echo "RANLIB=$target_ranlib" echo "AR=$target_ar"
fi fi
if test -n "$target_strip"; then if test -n "$target_as"; then
echo "STRIP=$target_strip" echo "AS=$target_as"
fi
if test -n "$target_ld"; then
echo "LD=$target_ld"
fi
if test -n "$target_nm"; then
echo "NM=$target_nm"
fi
if test -n "$target_objcopy"; then
echo "OBJCOPY=$target_objcopy"
fi
if test -n "$target_ranlib"; then
echo "RANLIB=$target_ranlib"
fi
if test -n "$target_strip"; then
echo "STRIP=$target_strip"
fi
fi fi
} }
write_container_target_makefile() {
echo "EXTRA_CFLAGS=$target_cflags"
if test -n "$container_cross_cc"; then
echo "CC=\$(DOCKER_SCRIPT) cc --cc $container_cross_cc -i qemu/$container_image -s $source_path --"
echo "CCAS=\$(DOCKER_SCRIPT) cc --cc $container_cross_cc -i qemu/$container_image -s $source_path --"
fi
echo "AR=\$(DOCKER_SCRIPT) cc --cc $container_cross_ar -i qemu/$container_image -s $source_path --"
echo "AS=\$(DOCKER_SCRIPT) cc --cc $container_cross_as -i qemu/$container_image -s $source_path --"
echo "LD=\$(DOCKER_SCRIPT) cc --cc $container_cross_ld -i qemu/$container_image -s $source_path --"
echo "NM=\$(DOCKER_SCRIPT) cc --cc $container_cross_nm -i qemu/$container_image -s $source_path --"
echo "OBJCOPY=\$(DOCKER_SCRIPT) cc --cc $container_cross_objcopy -i qemu/$container_image -s $source_path --"
echo "RANLIB=\$(DOCKER_SCRIPT) cc --cc $container_cross_ranlib -i qemu/$container_image -s $source_path --"
echo "STRIP=\$(DOCKER_SCRIPT) cc --cc $container_cross_strip -i qemu/$container_image -s $source_path --"
}
########################################## ##########################################
# check for vfio_user_server # check for vfio_user_server
@ -2237,7 +2242,6 @@ fi
# tests might fail. Prefer to keep the relevant files in their own # tests might fail. Prefer to keep the relevant files in their own
# directory and symlink the directory instead. # directory and symlink the directory instead.
LINKS="Makefile" LINKS="Makefile"
LINKS="$LINKS tests/tcg/Makefile.target"
LINKS="$LINKS pc-bios/optionrom/Makefile" LINKS="$LINKS pc-bios/optionrom/Makefile"
LINKS="$LINKS pc-bios/s390-ccw/Makefile" LINKS="$LINKS pc-bios/s390-ccw/Makefile"
LINKS="$LINKS pc-bios/vof/Makefile" LINKS="$LINKS pc-bios/vof/Makefile"
@ -2253,45 +2257,50 @@ for f in $LINKS ; do
fi fi
done done
echo "# Automatically generated by configure - do not modify" > Makefile.prereqs
# Mac OS X ships with a broken assembler # Mac OS X ships with a broken assembler
roms= roms=
probe_target_compiler i386-softmmu if test "$targetos" != "darwin" && test "$targetos" != "sunos" && \
if test -n "$target_cc" && test "$targetos" != "haiku" && test "$softmmu" = yes && \
test "$targetos" != "darwin" && test "$targetos" != "sunos" && \ probe_target_compiler i386-softmmu; then
test "$targetos" != "haiku" && test "$softmmu" = yes ; then
roms="pc-bios/optionrom" roms="pc-bios/optionrom"
config_mak=pc-bios/optionrom/config.mak config_mak=pc-bios/optionrom/config.mak
echo "# Automatically generated by configure - do not modify" > $config_mak echo "# Automatically generated by configure - do not modify" > $config_mak
echo "TOPSRC_DIR=$source_path" >> $config_mak echo "TOPSRC_DIR=$source_path" >> $config_mak
write_target_makefile >> $config_mak write_target_makefile pc-bios/optionrom/all >> $config_mak
fi fi
probe_target_compiler ppc-softmmu if test "$softmmu" = yes && probe_target_compiler ppc-softmmu; then
if test -n "$target_cc" && test "$softmmu" = yes; then
roms="$roms pc-bios/vof" roms="$roms pc-bios/vof"
config_mak=pc-bios/vof/config.mak config_mak=pc-bios/vof/config.mak
echo "# Automatically generated by configure - do not modify" > $config_mak echo "# Automatically generated by configure - do not modify" > $config_mak
echo "SRC_DIR=$source_path/pc-bios/vof" >> $config_mak echo "SRC_DIR=$source_path/pc-bios/vof" >> $config_mak
write_target_makefile >> $config_mak write_target_makefile pc-bios/vof/all >> $config_mak
fi fi
# Only build s390-ccw bios if the compiler has -march=z900 or -march=z10 # Only build s390-ccw bios if the compiler has -march=z900 or -march=z10
# (which is the lowest architecture level that Clang supports) # (which is the lowest architecture level that Clang supports)
probe_target_compiler s390x-softmmu if test "$softmmu" = yes && probe_target_compiler s390x-softmmu; then
if test -n "$target_cc" && test "$softmmu" = yes; then got_cross_cc=no
write_c_skeleton if test -n "$target_cc"; then
do_compiler "$target_cc" $target_cc_cflags -march=z900 -o $TMPO -c $TMPC write_c_skeleton
has_z900=$? do_compiler "$target_cc" $target_cc_cflags -march=z900 -o $TMPO -c $TMPC
if [ $has_z900 = 0 ] || do_compiler "$target_cc" $target_cc_cflags -march=z10 -msoft-float -Werror -o $TMPO -c $TMPC; then has_z900=$?
if [ $has_z900 != 0 ]; then if [ $has_z900 = 0 ] || do_compiler "$target_cc" $target_cc_cflags -march=z10 -msoft-float -Werror -o $TMPO -c $TMPC; then
echo "WARNING: Your compiler does not support the z900!" if [ $has_z900 != 0 ]; then
echo " The s390-ccw bios will only work with guest CPUs >= z10." echo "WARNING: Your compiler does not support the z900!"
echo " The s390-ccw bios will only work with guest CPUs >= z10."
fi
got_cross_cc=yes
fi fi
fi
if test "$got_cross_cc" = yes || test -n "$container_image"; then
roms="$roms pc-bios/s390-ccw" roms="$roms pc-bios/s390-ccw"
config_mak=pc-bios/s390-ccw/config-host.mak config_mak=pc-bios/s390-ccw/config-host.mak
echo "# Automatically generated by configure - do not modify" > $config_mak echo "# Automatically generated by configure - do not modify" > $config_mak
echo "SRC_PATH=$source_path/pc-bios/s390-ccw" >> $config_mak echo "SRC_PATH=$source_path/pc-bios/s390-ccw" >> $config_mak
write_target_makefile >> $config_mak write_target_makefile pc-bios/s390-ccw/all >> $config_mak
# SLOF is required for building the s390-ccw firmware on s390x, # SLOF is required for building the s390-ccw firmware on s390x,
# since it is using the libnet code from SLOF for network booting. # since it is using the libnet code from SLOF for network booting.
git_submodules="${git_submodules} roms/SLOF" git_submodules="${git_submodules} roms/SLOF"
@ -2370,9 +2379,14 @@ if test -n "$gdb_bin"; then
gdb_version=$($gdb_bin --version | head -n 1) gdb_version=$($gdb_bin --version | head -n 1)
if version_ge ${gdb_version##* } 9.1; then if version_ge ${gdb_version##* } 9.1; then
echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
else
gdb_bin=""
fi fi
fi fi
if test "$container" != no; then
echo "ENGINE=$container" >> $config_host_mak
fi
echo "ROMS=$roms" >> $config_host_mak echo "ROMS=$roms" >> $config_host_mak
echo "MAKE=$make" >> $config_host_mak echo "MAKE=$make" >> $config_host_mak
echo "PYTHON=$python" >> $config_host_mak echo "PYTHON=$python" >> $config_host_mak
@ -2445,22 +2459,21 @@ if test "$safe_stack" = "yes"; then
fi fi
# tests/tcg configuration # tests/tcg configuration
(makefile=tests/tcg/Makefile.prereqs (config_host_mak=tests/tcg/config-host.mak
echo "# Automatically generated by configure - do not modify" > $makefile mkdir -p tests/tcg
config_host_mak=tests/tcg/config-host.mak
echo "# Automatically generated by configure - do not modify" > $config_host_mak echo "# Automatically generated by configure - do not modify" > $config_host_mak
echo "SRC_PATH=$source_path" >> $config_host_mak echo "SRC_PATH=$source_path" >> $config_host_mak
echo "HOST_CC=$host_cc" >> $config_host_mak echo "HOST_CC=$host_cc" >> $config_host_mak
# versioned checked in the main config_host.mak above
if test -n "$gdb_bin"; then
echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
fi
tcg_tests_targets= tcg_tests_targets=
for target in $target_list; do for target in $target_list; do
arch=${target%%-*} arch=${target%%-*}
config_target_mak=tests/tcg/config-$target.mak
echo "# Automatically generated by configure - do not modify" > $config_target_mak
echo "TARGET_NAME=$arch" >> "$config_target_mak"
case $target in case $target in
xtensa*-linux-user) xtensa*-linux-user)
# the toolchain is not complete with headers, only build softmmu tests # the toolchain is not complete with headers, only build softmmu tests
@ -2475,85 +2488,22 @@ for target in $target_list; do
;; ;;
esac esac
probe_target_compiler $target if probe_target_compiler $target; then
if test $got_cross_cc = yes; then test -n "$container_image" && build_static=y
# Test for compiler features for optional tests. We only do this mkdir -p "tests/tcg/$target"
# for cross compilers because ensuring the docker containers based config_target_mak=tests/tcg/$target/config-target.mak
# compilers is a requirememt for adding a new test that needs a ln -sf "$source_path/tests/tcg/Makefile.target" "tests/tcg/$target/Makefile"
# compiler feature. echo "# Automatically generated by configure - do not modify" > "$config_target_mak"
echo "TARGET_NAME=$arch" >> "$config_target_mak"
echo "TARGET=$target" >> "$config_target_mak"
write_target_makefile "build-tcg-tests-$target" >> "$config_target_mak"
echo "BUILD_STATIC=$build_static" >> "$config_target_mak" echo "BUILD_STATIC=$build_static" >> "$config_target_mak"
write_target_makefile >> "$config_target_mak"
case $target in
aarch64-*)
if do_compiler "$target_cc" $target_cflags \
-march=armv8.1-a+sve -o $TMPE $TMPC; then
echo "CROSS_CC_HAS_SVE=y" >> "$config_target_mak"
fi
if do_compiler "$target_cc" $target_cflags \
-march=armv8.1-a+sve2 -o $TMPE $TMPC; then
echo "CROSS_CC_HAS_SVE2=y" >> "$config_target_mak"
fi
if do_compiler "$target_cc" $target_cflags \
-march=armv8.3-a -o $TMPE $TMPC; then
echo "CROSS_CC_HAS_ARMV8_3=y" >> "$config_target_mak"
fi
if do_compiler "$target_cc" $target_cflags \
-mbranch-protection=standard -o $TMPE $TMPC; then
echo "CROSS_CC_HAS_ARMV8_BTI=y" >> "$config_target_mak"
fi
if do_compiler "$target_cc" $target_cflags \
-march=armv8.5-a+memtag -o $TMPE $TMPC; then
echo "CROSS_CC_HAS_ARMV8_MTE=y" >> "$config_target_mak"
fi
;;
ppc*)
if do_compiler "$target_cc" $target_cflags \
-mpower8-vector -o $TMPE $TMPC; then
echo "CROSS_CC_HAS_POWER8_VECTOR=y" >> "$config_target_mak"
fi
if do_compiler "$target_cc" $target_cflags \
-mpower10 -o $TMPE $TMPC; then
echo "CROSS_CC_HAS_POWER10=y" >> "$config_target_mak"
fi
;;
i386-linux-user)
if do_compiler "$target_cc" $target_cflags \
-Werror -fno-pie -o $TMPE $TMPC; then
echo "CROSS_CC_HAS_I386_NOPIE=y" >> "$config_target_mak"
fi
;;
esac
elif test -n "$container_image"; then
echo "build-tcg-tests-$target: docker-image-$container_image" >> $makefile
echo "BUILD_STATIC=y" >> "$config_target_mak"
write_container_target_makefile >> "$config_target_mak"
case $target in
aarch64-*)
echo "CROSS_CC_HAS_SVE=y" >> "$config_target_mak"
echo "CROSS_CC_HAS_SVE2=y" >> "$config_target_mak"
echo "CROSS_CC_HAS_ARMV8_3=y" >> "$config_target_mak"
echo "CROSS_CC_HAS_ARMV8_BTI=y" >> "$config_target_mak"
echo "CROSS_CC_HAS_ARMV8_MTE=y" >> "$config_target_mak"
;;
ppc*)
echo "CROSS_CC_HAS_POWER8_VECTOR=y" >> "$config_target_mak"
echo "CROSS_CC_HAS_POWER10=y" >> "$config_target_mak"
;;
i386-linux-user)
echo "CROSS_CC_HAS_I386_NOPIE=y" >> "$config_target_mak"
;;
esac
got_cross_cc=yes
fi
if test $got_cross_cc = yes; then
mkdir -p tests/tcg/$target
echo "QEMU=$PWD/$qemu" >> "$config_target_mak" echo "QEMU=$PWD/$qemu" >> "$config_target_mak"
echo "run-tcg-tests-$target: $qemu\$(EXESUF)" >> $makefile echo "run-tcg-tests-$target: $qemu\$(EXESUF)" >> Makefile.prereqs
tcg_tests_targets="$tcg_tests_targets $target" tcg_tests_targets="$tcg_tests_targets $target"
fi fi
done done
echo "TCG_TESTS_TARGETS=$tcg_tests_targets" >> $makefile) echo "TCG_TESTS_TARGETS=$tcg_tests_targets" >> config-host.mak)
if test "$skip_meson" = no; then if test "$skip_meson" = no; then
cross="config-meson.cross.new" cross="config-meson.cross.new"

View File

@ -10,6 +10,7 @@ bytedance.com ByteDance
cmss.chinamobile.com China Mobile cmss.chinamobile.com China Mobile
citrix.com Citrix citrix.com Citrix
crudebyte.com Crudebyte crudebyte.com Crudebyte
chinatelecom.cn China Telecom
eldorado.org.br Instituto de Pesquisas Eldorado eldorado.org.br Instituto de Pesquisas Eldorado
fujitsu.com Fujitsu fujitsu.com Fujitsu
google.com Google google.com Google
@ -19,6 +20,7 @@ ibm.com IBM
igalia.com Igalia igalia.com Igalia
intel.com Intel intel.com Intel
linaro.org Linaro linaro.org Linaro
loongson.cn Loongson Technology
lwn.net LWN lwn.net LWN
microsoft.com Microsoft microsoft.com Microsoft
mvista.com MontaVista mvista.com MontaVista

View File

@ -19,3 +19,9 @@ edu.cn
# Boston University # Boston University
bu.edu bu.edu
# Institute of Software Chinese Academy of Sciences
iscas.ac.cn
# Université Grenoble Alpes
univ-grenoble-alpes.fr

View File

@ -34,3 +34,6 @@ bmeng.cn@gmail.com
liq3ea@gmail.com liq3ea@gmail.com
chetan4windows@gmail.com chetan4windows@gmail.com
akihiko.odaki@gmail.com akihiko.odaki@gmail.com
paul@nowt.org
git@xen0n.name
simon@simonsafar.com

View File

@ -20,6 +20,9 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
/* Store last executed instruction on each vCPU as a GString */ /* Store last executed instruction on each vCPU as a GString */
GArray *last_exec; GArray *last_exec;
static GPtrArray *imatches;
static GArray *amatches;
/** /**
* Add memory read or write information to current instruction log * Add memory read or write information to current instruction log
*/ */
@ -85,12 +88,13 @@ static void vcpu_insn_exec(unsigned int cpu_index, void *udata)
static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
{ {
struct qemu_plugin_insn *insn; struct qemu_plugin_insn *insn;
uint64_t insn_vaddr; bool skip = (imatches || amatches);
uint32_t insn_opcode;
char *insn_disas;
size_t n = qemu_plugin_tb_n_insns(tb); size_t n = qemu_plugin_tb_n_insns(tb);
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
char *insn_disas;
uint64_t insn_vaddr;
/* /*
* `insn` is shared between translations in QEMU, copy needed data here. * `insn` is shared between translations in QEMU, copy needed data here.
* `output` is never freed as it might be used multiple times during * `output` is never freed as it might be used multiple times during
@ -99,20 +103,55 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
* a limitation for CISC architectures. * a limitation for CISC architectures.
*/ */
insn = qemu_plugin_tb_get_insn(tb, i); insn = qemu_plugin_tb_get_insn(tb, i);
insn_vaddr = qemu_plugin_insn_vaddr(insn);
insn_opcode = *((uint32_t *)qemu_plugin_insn_data(insn));
insn_disas = qemu_plugin_insn_disas(insn); insn_disas = qemu_plugin_insn_disas(insn);
char *output = g_strdup_printf("0x%"PRIx64", 0x%"PRIx32", \"%s\"", insn_vaddr = qemu_plugin_insn_vaddr(insn);
insn_vaddr, insn_opcode, insn_disas);
/* Register callback on memory read or write */ /*
qemu_plugin_register_vcpu_mem_cb(insn, vcpu_mem, * If we are filtering we better check out if we have any
QEMU_PLUGIN_CB_NO_REGS, * hits. The skip "latches" so we can track memory accesses
QEMU_PLUGIN_MEM_RW, NULL); * after the instruction we care about.
*/
if (skip && imatches) {
int j;
for (j = 0; j < imatches->len && skip; j++) {
char *m = g_ptr_array_index(imatches, j);
if (g_str_has_prefix(insn_disas, m)) {
skip = false;
}
}
}
if (skip && amatches) {
int j;
for (j = 0; j < amatches->len && skip; j++) {
uint64_t v = g_array_index(amatches, uint64_t, j);
if (v == insn_vaddr) {
skip = false;
}
}
}
if (skip) {
g_free(insn_disas);
} else {
uint32_t insn_opcode;
insn_opcode = *((uint32_t *)qemu_plugin_insn_data(insn));
char *output = g_strdup_printf("0x%"PRIx64", 0x%"PRIx32", \"%s\"",
insn_vaddr, insn_opcode, insn_disas);
/* Register callback on memory read or write */
qemu_plugin_register_vcpu_mem_cb(insn, vcpu_mem,
QEMU_PLUGIN_CB_NO_REGS,
QEMU_PLUGIN_MEM_RW, NULL);
/* Register callback on instruction */
qemu_plugin_register_vcpu_insn_exec_cb(insn, vcpu_insn_exec,
QEMU_PLUGIN_CB_NO_REGS, output);
/* reset skip */
skip = (imatches || amatches);
}
/* Register callback on instruction */
qemu_plugin_register_vcpu_insn_exec_cb(insn, vcpu_insn_exec,
QEMU_PLUGIN_CB_NO_REGS, output);
} }
} }
@ -132,6 +171,25 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
} }
} }
/* Add a match to the array of matches */
static void parse_insn_match(char *match)
{
if (!imatches) {
imatches = g_ptr_array_new();
}
g_ptr_array_add(imatches, match);
}
static void parse_vaddr_match(char *match)
{
uint64_t v = g_ascii_strtoull(match, NULL, 16);
if (!amatches) {
amatches = g_array_new(false, true, sizeof(uint64_t));
}
g_array_append_val(amatches, v);
}
/** /**
* Install the plugin * Install the plugin
*/ */
@ -145,6 +203,19 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
*/ */
last_exec = g_array_new(FALSE, FALSE, sizeof(GString *)); last_exec = g_array_new(FALSE, FALSE, sizeof(GString *));
for (int i = 0; i < argc; i++) {
char *opt = argv[i];
g_autofree char **tokens = g_strsplit(opt, "=", 2);
if (g_strcmp0(tokens[0], "ifilter") == 0) {
parse_insn_match(tokens[1]);
} else if (g_strcmp0(tokens[0], "afilter") == 0) {
parse_vaddr_match(tokens[1]);
} else {
fprintf(stderr, "option parsing failed: %s\n", opt);
return -1;
}
}
/* Register translation block and exit callbacks */ /* Register translation block and exit callbacks */
qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans); qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
qemu_plugin_register_atexit_cb(id, plugin_exit, NULL); qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);

41
disas.c
View File

@ -83,18 +83,18 @@ static int print_insn_objdump(bfd_vma pc, disassemble_info *info,
const char *prefix) const char *prefix)
{ {
int i, n = info->buffer_length; int i, n = info->buffer_length;
uint8_t *buf = g_malloc(n); g_autofree uint8_t *buf = g_malloc(n);
info->read_memory_func(pc, buf, n, info); if (info->read_memory_func(pc, buf, n, info) == 0) {
for (i = 0; i < n; ++i) {
for (i = 0; i < n; ++i) { if (i % 32 == 0) {
if (i % 32 == 0) { info->fprintf_func(info->stream, "\n%s: ", prefix);
info->fprintf_func(info->stream, "\n%s: ", prefix); }
info->fprintf_func(info->stream, "%02x", buf[i]);
} }
info->fprintf_func(info->stream, "%02x", buf[i]); } else {
info->fprintf_func(info->stream, "unable to read memory");
} }
g_free(buf);
return n; return n;
} }
@ -239,7 +239,7 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
} }
} }
static int plugin_printf(FILE *stream, const char *fmt, ...) static int gstring_printf(FILE *stream, const char *fmt, ...)
{ {
/* We abuse the FILE parameter to pass a GString. */ /* We abuse the FILE parameter to pass a GString. */
GString *s = (GString *)stream; GString *s = (GString *)stream;
@ -270,7 +270,7 @@ char *plugin_disas(CPUState *cpu, uint64_t addr, size_t size)
GString *ds = g_string_new(NULL); GString *ds = g_string_new(NULL);
initialize_debug_target(&s, cpu); initialize_debug_target(&s, cpu);
s.info.fprintf_func = plugin_printf; s.info.fprintf_func = gstring_printf;
s.info.stream = (FILE *)ds; /* abuse this slot */ s.info.stream = (FILE *)ds; /* abuse this slot */
s.info.buffer_vma = addr; s.info.buffer_vma = addr;
s.info.buffer_length = size; s.info.buffer_length = size;
@ -358,15 +358,19 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
{ {
int count, i; int count, i;
CPUDebug s; CPUDebug s;
g_autoptr(GString) ds = g_string_new("");
initialize_debug_target(&s, cpu); initialize_debug_target(&s, cpu);
s.info.fprintf_func = qemu_fprintf; s.info.fprintf_func = gstring_printf;
s.info.stream = (FILE *)ds; /* abuse this slot */
if (is_physical) { if (is_physical) {
s.info.read_memory_func = physical_read_memory; s.info.read_memory_func = physical_read_memory;
} }
s.info.buffer_vma = pc; s.info.buffer_vma = pc;
if (s.info.cap_arch >= 0 && cap_disas_monitor(&s.info, pc, nb_insn)) { if (s.info.cap_arch >= 0 && cap_disas_monitor(&s.info, pc, nb_insn)) {
monitor_puts(mon, ds->str);
return; return;
} }
@ -376,13 +380,16 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
return; return;
} }
for(i = 0; i < nb_insn; i++) { for (i = 0; i < nb_insn; i++) {
monitor_printf(mon, "0x" TARGET_FMT_lx ": ", pc); g_string_append_printf(ds, "0x" TARGET_FMT_lx ": ", pc);
count = s.info.print_insn(pc, &s.info); count = s.info.print_insn(pc, &s.info);
monitor_printf(mon, "\n"); g_string_append_c(ds, '\n');
if (count < 0) if (count < 0) {
break; break;
}
pc += count; pc += count;
} }
monitor_puts(mon, ds->str);
} }
#endif #endif

View File

@ -191,37 +191,43 @@ bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size)
size_t tsize = MIN(sizeof(cap_buf) - csize, size); size_t tsize = MIN(sizeof(cap_buf) - csize, size);
const uint8_t *cbuf = cap_buf; const uint8_t *cbuf = cap_buf;
info->read_memory_func(pc + csize, cap_buf + csize, tsize, info); if (info->read_memory_func(pc + csize, cap_buf + csize, tsize, info) == 0) {
csize += tsize; csize += tsize;
size -= tsize; size -= tsize;
while (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) { while (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) {
cap_dump_insn(info, insn); cap_dump_insn(info, insn);
} }
/* If the target memory is not consumed, go back for more... */
if (size != 0) {
/*
* ... taking care to move any remaining fractional insn
* to the beginning of the buffer.
*/
if (csize != 0) {
memmove(cap_buf, cbuf, csize);
}
continue;
}
/* If the target memory is not consumed, go back for more... */
if (size != 0) {
/* /*
* ... taking care to move any remaining fractional insn * Since the target memory is consumed, we should not have
* to the beginning of the buffer. * a remaining fractional insn.
*/ */
if (csize != 0) { if (csize != 0) {
memmove(cap_buf, cbuf, csize); info->fprintf_func(info->stream,
"Disassembler disagrees with translator "
"over instruction decoding\n"
"Please report this to qemu-devel@nongnu.org\n");
} }
continue; break;
}
/* } else {
* Since the target memory is consumed, we should not have
* a remaining fractional insn.
*/
if (csize != 0) {
info->fprintf_func(info->stream, info->fprintf_func(info->stream,
"Disassembler disagrees with translator " "0x%08" PRIx64 ": unable to read memory\n", pc);
"over instruction decoding\n" break;
"Please report this to qemu-devel@nongnu.org\n");
} }
break;
} }
cs_close(&handle); cs_close(&handle);
@ -286,16 +292,23 @@ bool cap_disas_monitor(disassemble_info *info, uint64_t pc, int count)
/* Make certain that we can make progress. */ /* Make certain that we can make progress. */
assert(tsize != 0); assert(tsize != 0);
info->read_memory_func(pc + csize, cap_buf + csize, tsize, info); if (info->read_memory_func(pc + csize, cap_buf + csize,
csize += tsize; tsize, info) == 0)
{
csize += tsize;
if (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) { if (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) {
cap_dump_insn(info, insn); cap_dump_insn(info, insn);
if (--count <= 0) { if (--count <= 0) {
break; break;
}
} }
memmove(cap_buf, cbuf, csize);
} else {
info->fprintf_func(info->stream,
"0x%08" PRIx64 ": unable to read memory\n", pc);
break;
} }
memmove(cap_buf, cbuf, csize);
} }
cs_close(&handle); cs_close(&handle);

View File

@ -110,11 +110,6 @@ details are opaque to plugins. The plugin is able to query select
details of instructions and system configuration only through the details of instructions and system configuration only through the
exported *qemu_plugin* functions. exported *qemu_plugin* functions.
API
~~~
.. kernel-doc:: include/qemu/qemu-plugin.h
Internals Internals
--------- ---------
@ -150,12 +145,141 @@ Example Plugins
There are a number of plugins included with QEMU and you are There are a number of plugins included with QEMU and you are
encouraged to contribute your own plugins plugins upstream. There is a encouraged to contribute your own plugins plugins upstream. There is a
``contrib/plugins`` directory where they can go. ``contrib/plugins`` directory where they can go. There are also some
basic plugins that are used to test and exercise the API during the
``make check-tcg`` target in ``tests\plugins``.
- tests/plugins - tests/plugins/empty.c
These are some basic plugins that are used to test and exercise the Purely a test plugin for measuring the overhead of the plugins system
API during the ``make check-tcg`` target. itself. Does no instrumentation.
- tests/plugins/bb.c
A very basic plugin which will measure execution in course terms as
each basic block is executed. By default the results are shown once
execution finishes::
$ qemu-aarch64 -plugin tests/plugin/libbb.so \
-d plugin ./tests/tcg/aarch64-linux-user/sha1
SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6
bb's: 2277338, insns: 158483046
Behaviour can be tweaked with the following arguments:
* inline=true|false
Use faster inline addition of a single counter. Not per-cpu and not
thread safe.
* idle=true|false
Dump the current execution stats whenever the guest vCPU idles
- tests/plugins/insn.c
This is a basic instruction level instrumentation which can count the
number of instructions executed on each core/thread::
$ qemu-aarch64 -plugin tests/plugin/libinsn.so \
-d plugin ./tests/tcg/aarch64-linux-user/threadcount
Created 10 threads
Done
cpu 0 insns: 46765
cpu 1 insns: 3694
cpu 2 insns: 3694
cpu 3 insns: 2994
cpu 4 insns: 1497
cpu 5 insns: 1497
cpu 6 insns: 1497
cpu 7 insns: 1497
total insns: 63135
Behaviour can be tweaked with the following arguments:
* inline=true|false
Use faster inline addition of a single counter. Not per-cpu and not
thread safe.
* sizes=true|false
Give a summary of the instruction sizes for the execution
* match=<string>
Only instrument instructions matching the string prefix. Will show
some basic stats including how many instructions have executed since
the last execution. For example::
$ qemu-aarch64 -plugin tests/plugin/libinsn.so,match=bl \
-d plugin ./tests/tcg/aarch64-linux-user/sha512-vector
...
0x40069c, 'bl #0x4002b0', 10 hits, 1093 match hits, Δ+1257 since last match, 98 avg insns/match
0x4006ac, 'bl #0x403690', 10 hits, 1094 match hits, Δ+47 since last match, 98 avg insns/match
0x4037fc, 'bl #0x4002b0', 18 hits, 1095 match hits, Δ+22 since last match, 98 avg insns/match
0x400720, 'bl #0x403690', 10 hits, 1096 match hits, Δ+58 since last match, 98 avg insns/match
0x4037fc, 'bl #0x4002b0', 19 hits, 1097 match hits, Δ+22 since last match, 98 avg insns/match
0x400730, 'bl #0x403690', 10 hits, 1098 match hits, Δ+33 since last match, 98 avg insns/match
0x4037ac, 'bl #0x4002b0', 12 hits, 1099 match hits, Δ+20 since last match, 98 avg insns/match
...
For more detailed execution tracing see the ``execlog`` plugin for
other options.
- tests/plugins/mem.c
Basic instruction level memory instrumentation::
$ qemu-aarch64 -plugin tests/plugin/libmem.so,inline=true \
-d plugin ./tests/tcg/aarch64-linux-user/sha1
SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6
inline mem accesses: 79525013
Behaviour can be tweaked with the following arguments:
* inline=true|false
Use faster inline addition of a single counter. Not per-cpu and not
thread safe.
* callback=true|false
Use callbacks on each memory instrumentation.
* hwaddr=true|false
Count IO accesses (only for system emulation)
- tests/plugins/syscall.c
A basic syscall tracing plugin. This only works for user-mode. By
default it will give a summary of syscall stats at the end of the
run::
$ qemu-aarch64 -plugin tests/plugin/libsyscall \
-d plugin ./tests/tcg/aarch64-linux-user/threadcount
Created 10 threads
Done
syscall no. calls errors
226 12 0
99 11 11
115 11 0
222 11 0
93 10 0
220 10 0
233 10 0
215 8 0
214 4 0
134 2 0
64 2 0
96 1 0
94 1 0
80 1 0
261 1 0
78 1 0
160 1 0
135 1 0
- contrib/plugins/hotblocks.c - contrib/plugins/hotblocks.c
@ -172,7 +296,7 @@ slightly faster (but not thread safe) counters.
Example:: Example::
./aarch64-linux-user/qemu-aarch64 \ $ qemu-aarch64 \
-plugin contrib/plugins/libhotblocks.so -d plugin \ -plugin contrib/plugins/libhotblocks.so -d plugin \
./tests/tcg/aarch64-linux-user/sha1 ./tests/tcg/aarch64-linux-user/sha1
SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6 SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6
@ -186,7 +310,7 @@ Example::
Similar to hotblocks but this time tracks memory accesses:: Similar to hotblocks but this time tracks memory accesses::
./aarch64-linux-user/qemu-aarch64 \ $ qemu-aarch64 \
-plugin contrib/plugins/libhotpages.so -d plugin \ -plugin contrib/plugins/libhotpages.so -d plugin \
./tests/tcg/aarch64-linux-user/sha1 ./tests/tcg/aarch64-linux-user/sha1
SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6 SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6
@ -220,7 +344,7 @@ counted. You can give a value to the ``count`` argument for a class of
instructions to break it down fully, so for example to see all the system instructions to break it down fully, so for example to see all the system
registers accesses:: registers accesses::
./aarch64-softmmu/qemu-system-aarch64 $(QEMU_ARGS) \ $ qemu-system-aarch64 $(QEMU_ARGS) \
-append "root=/dev/sda2 systemd.unit=benchmark.service" \ -append "root=/dev/sda2 systemd.unit=benchmark.service" \
-smp 4 -plugin ./contrib/plugins/libhowvec.so,count=sreg -d plugin -smp 4 -plugin ./contrib/plugins/libhowvec.so,count=sreg -d plugin
@ -288,10 +412,10 @@ for the plugin is a path for the socket the two instances will
communicate over:: communicate over::
./sparc-softmmu/qemu-system-sparc -monitor none -parallel none \ $ qemu-system-sparc -monitor none -parallel none \
-net none -M SS-20 -m 256 -kernel day11/zImage.elf \ -net none -M SS-20 -m 256 -kernel day11/zImage.elf \
-plugin ./contrib/plugins/liblockstep.so,sockpath=lockstep-sparc.sock \ -plugin ./contrib/plugins/liblockstep.so,sockpath=lockstep-sparc.sock \
-d plugin,nochain -d plugin,nochain
which will eventually report:: which will eventually report::
@ -346,9 +470,9 @@ The execlog tool traces executed instructions with memory access. It can be used
for debugging and security analysis purposes. for debugging and security analysis purposes.
Please be aware that this will generate a lot of output. Please be aware that this will generate a lot of output.
The plugin takes no argument:: The plugin needs default argument::
qemu-system-arm $(QEMU_ARGS) \ $ qemu-system-arm $(QEMU_ARGS) \
-plugin ./contrib/plugins/libexeclog.so -d plugin -plugin ./contrib/plugins/libexeclog.so -d plugin
which will output an execution trace following this structure:: which will output an execution trace following this structure::
@ -364,13 +488,20 @@ which will output an execution trace following this structure::
0, 0xd34, 0xf9c8f000, "bl #0x10c8" 0, 0xd34, 0xf9c8f000, "bl #0x10c8"
0, 0x10c8, 0xfff96c43, "ldr r3, [r0, #0x44]", load, 0x200000e4, RAM 0, 0x10c8, 0xfff96c43, "ldr r3, [r0, #0x44]", load, 0x200000e4, RAM
the output can be filtered to only track certain instructions or
addresses using the ``ifilter`` or ``afilter`` options. You can stack the
arguments if required::
$ qemu-system-arm $(QEMU_ARGS) \
-plugin ./contrib/plugins/libexeclog.so,ifilter=st1w,afilter=0x40001808 -d plugin
- contrib/plugins/cache.c - contrib/plugins/cache.c
Cache modelling plugin that measures the performance of a given L1 cache Cache modelling plugin that measures the performance of a given L1 cache
configuration, and optionally a unified L2 per-core cache when a given working configuration, and optionally a unified L2 per-core cache when a given working
set is run:: set is run::
qemu-x86_64 -plugin ./contrib/plugins/libcache.so \ $ qemu-x86_64 -plugin ./contrib/plugins/libcache.so \
-d plugin -D cache.log ./tests/tcg/x86_64-linux-user/float_convs -d plugin -D cache.log ./tests/tcg/x86_64-linux-user/float_convs
will report the following:: will report the following::
@ -441,3 +572,13 @@ The plugin has a number of arguments, all of them are optional:
associativity of the L2 cache, respectively. Setting any of the L2 associativity of the L2 cache, respectively. Setting any of the L2
configuration arguments implies ``l2=on``. configuration arguments implies ``l2=on``.
(default: N = 2097152 (2MB), B = 64, A = 16) (default: N = 2097152 (2MB), B = 64, A = 16)
API
---
The following API is generated from the inline documentation in
``include/qemu/qemu-plugin.h``. Please ensure any updates to the API
include the full kernel-doc annotations.
.. kernel-doc:: include/qemu/qemu-plugin.h

View File

@ -716,7 +716,7 @@ message. Here's the implementation of the "info roms" HMP command::
if (hmp_handle_error(mon, err)) { if (hmp_handle_error(mon, err)) {
return; return;
} }
monitor_printf(mon, "%s", info->human_readable_text); monitor_puts(mon, info->human_readable_text);
} }
Also, you have to add the function's prototype to the hmp.h file. Also, you have to add the function's prototype to the hmp.h file.

View File

@ -29,7 +29,7 @@
#include "qemu/ctype.h" #include "qemu/ctype.h"
#include "qemu/cutils.h" #include "qemu/cutils.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "trace/trace-root.h" #include "trace.h"
#include "exec/gdbstub.h" #include "exec/gdbstub.h"
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
#include "qemu.h" #include "qemu.h"
@ -45,12 +45,14 @@
#include "qemu/sockets.h" #include "qemu/sockets.h"
#include "sysemu/hw_accel.h" #include "sysemu/hw_accel.h"
#include "sysemu/kvm.h"
#include "sysemu/runstate.h" #include "sysemu/runstate.h"
#include "semihosting/semihost.h" #include "semihosting/semihost.h"
#include "exec/exec-all.h" #include "exec/exec-all.h"
#include "exec/hwaddr.h"
#include "sysemu/replay.h" #include "sysemu/replay.h"
#include "internals.h"
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
#define GDB_ATTACHED "0" #define GDB_ATTACHED "0"
#else #else
@ -383,27 +385,13 @@ static void init_gdbserver_state(void)
gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4); gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4);
/* /*
* In replay mode all events will come from the log and can't be * What single-step modes are supported is accelerator dependent.
* suppressed otherwise we would break determinism. However as those * By default try to use no IRQs and no timers while single
* events are tied to the number of executed instructions we won't see * stepping so as to make single stepping like a typical ICE HW step.
* them occurring every time we single step.
*/
if (replay_mode != REPLAY_MODE_NONE) {
gdbserver_state.supported_sstep_flags = SSTEP_ENABLE;
} else if (kvm_enabled()) {
gdbserver_state.supported_sstep_flags = kvm_get_supported_sstep_flags();
} else {
gdbserver_state.supported_sstep_flags =
SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
}
/*
* By default use no IRQs and no timers while single stepping so as to
* make single stepping like an ICE HW step.
*/ */
gdbserver_state.supported_sstep_flags = accel_supported_gdbstub_sstep_flags();
gdbserver_state.sstep_flags = SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER; gdbserver_state.sstep_flags = SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags; gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags;
} }
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
@ -1026,130 +1014,16 @@ void gdb_register_coprocessor(CPUState *cpu,
} }
} }
#ifndef CONFIG_USER_ONLY
/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
{
static const int xlat[] = {
[GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
[GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
[GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
};
CPUClass *cc = CPU_GET_CLASS(cpu);
int cputype = xlat[gdbtype];
if (cc->gdb_stop_before_watchpoint) {
cputype |= BP_STOP_BEFORE_ACCESS;
}
return cputype;
}
#endif
static int gdb_breakpoint_insert(int type, target_ulong addr, target_ulong len)
{
CPUState *cpu;
int err = 0;
if (kvm_enabled()) {
return kvm_insert_breakpoint(gdbserver_state.c_cpu, addr, len, type);
}
switch (type) {
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
CPU_FOREACH(cpu) {
err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
if (err) {
break;
}
}
return err;
#ifndef CONFIG_USER_ONLY
case GDB_WATCHPOINT_WRITE:
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
CPU_FOREACH(cpu) {
err = cpu_watchpoint_insert(cpu, addr, len,
xlat_gdb_type(cpu, type), NULL);
if (err) {
break;
}
}
return err;
#endif
default:
return -ENOSYS;
}
}
static int gdb_breakpoint_remove(int type, target_ulong addr, target_ulong len)
{
CPUState *cpu;
int err = 0;
if (kvm_enabled()) {
return kvm_remove_breakpoint(gdbserver_state.c_cpu, addr, len, type);
}
switch (type) {
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
CPU_FOREACH(cpu) {
err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
if (err) {
break;
}
}
return err;
#ifndef CONFIG_USER_ONLY
case GDB_WATCHPOINT_WRITE:
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
CPU_FOREACH(cpu) {
err = cpu_watchpoint_remove(cpu, addr, len,
xlat_gdb_type(cpu, type));
if (err)
break;
}
return err;
#endif
default:
return -ENOSYS;
}
}
static inline void gdb_cpu_breakpoint_remove_all(CPUState *cpu)
{
cpu_breakpoint_remove_all(cpu, BP_GDB);
#ifndef CONFIG_USER_ONLY
cpu_watchpoint_remove_all(cpu, BP_GDB);
#endif
}
static void gdb_process_breakpoint_remove_all(GDBProcess *p) static void gdb_process_breakpoint_remove_all(GDBProcess *p)
{ {
CPUState *cpu = get_first_cpu_in_process(p); CPUState *cpu = get_first_cpu_in_process(p);
while (cpu) { while (cpu) {
gdb_cpu_breakpoint_remove_all(cpu); gdb_breakpoint_remove_all(cpu);
cpu = gdb_next_cpu_in_process(cpu); cpu = gdb_next_cpu_in_process(cpu);
} }
} }
static void gdb_breakpoint_remove_all(void)
{
CPUState *cpu;
if (kvm_enabled()) {
kvm_remove_all_breakpoints(gdbserver_state.c_cpu);
return;
}
CPU_FOREACH(cpu) {
gdb_cpu_breakpoint_remove_all(cpu);
}
}
static void gdb_set_cpu_pc(target_ulong pc) static void gdb_set_cpu_pc(target_ulong pc)
{ {
@ -1681,7 +1555,8 @@ static void handle_insert_bp(GArray *params, void *user_ctx)
return; return;
} }
res = gdb_breakpoint_insert(get_param(params, 0)->val_ul, res = gdb_breakpoint_insert(gdbserver_state.c_cpu,
get_param(params, 0)->val_ul,
get_param(params, 1)->val_ull, get_param(params, 1)->val_ull,
get_param(params, 2)->val_ull); get_param(params, 2)->val_ull);
if (res >= 0) { if (res >= 0) {
@ -1704,7 +1579,8 @@ static void handle_remove_bp(GArray *params, void *user_ctx)
return; return;
} }
res = gdb_breakpoint_remove(get_param(params, 0)->val_ul, res = gdb_breakpoint_remove(gdbserver_state.c_cpu,
get_param(params, 0)->val_ul,
get_param(params, 1)->val_ull, get_param(params, 1)->val_ull,
get_param(params, 2)->val_ull); get_param(params, 2)->val_ull);
if (res >= 0) { if (res >= 0) {
@ -2555,7 +2431,7 @@ static void handle_target_halt(GArray *params, void *user_ctx)
* because gdb is doing an initial connect and the state * because gdb is doing an initial connect and the state
* should be cleaned up. * should be cleaned up.
*/ */
gdb_breakpoint_remove_all(); gdb_breakpoint_remove_all(gdbserver_state.c_cpu);
} }
static int gdb_handle_packet(const char *line_buf) static int gdb_handle_packet(const char *line_buf)
@ -3570,8 +3446,8 @@ int gdbserver_start(const char *device)
return -1; return -1;
} }
if (kvm_enabled() && !kvm_supports_guest_debug()) { if (!gdb_supports_guest_debug()) {
error_report("gdbstub: KVM doesn't support guest debugging"); error_report("gdbstub: current accelerator doesn't support guest debugging");
return -1; return -1;
} }

17
gdbstub/internals.h Normal file
View File

@ -0,0 +1,17 @@
/*
* gdbstub internals
*
* Copyright (c) 2022 Linaro Ltd
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef _INTERNALS_H_
#define _INTERNALS_H_
bool gdb_supports_guest_debug(void);
int gdb_breakpoint_insert(CPUState *cs, int type, hwaddr addr, hwaddr len);
int gdb_breakpoint_remove(CPUState *cs, int type, hwaddr addr, hwaddr len);
void gdb_breakpoint_remove_all(CPUState *cs);
#endif /* _INTERNALS_H_ */

9
gdbstub/meson.build Normal file
View File

@ -0,0 +1,9 @@
#
# The main gdbstub still relies on per-build definitions of various
# types. The bits pushed to softmmu/user.c try to use guest agnostic
# types such as hwaddr.
#
specific_ss.add(files('gdbstub.c'))
softmmu_ss.add(files('softmmu.c'))
user_ss.add(files('user.c'))

51
gdbstub/softmmu.c Normal file
View File

@ -0,0 +1,51 @@
/*
* gdb server stub - softmmu specific bits
*
* Debug integration depends on support from the individual
* accelerators so most of this involves calling the ops helpers.
*
* Copyright (c) 2022 Linaro Ltd
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "qemu/osdep.h"
#include "exec/gdbstub.h"
#include "exec/hwaddr.h"
#include "sysemu/cpus.h"
#include "internals.h"
bool gdb_supports_guest_debug(void)
{
const AccelOpsClass *ops = cpus_get_accel();
if (ops->supports_guest_debug) {
return ops->supports_guest_debug();
}
return false;
}
int gdb_breakpoint_insert(CPUState *cs, int type, hwaddr addr, hwaddr len)
{
const AccelOpsClass *ops = cpus_get_accel();
if (ops->insert_breakpoint) {
return ops->insert_breakpoint(cs, type, addr, len);
}
return -ENOSYS;
}
int gdb_breakpoint_remove(CPUState *cs, int type, hwaddr addr, hwaddr len)
{
const AccelOpsClass *ops = cpus_get_accel();
if (ops->remove_breakpoint) {
return ops->remove_breakpoint(cs, type, addr, len);
}
return -ENOSYS;
}
void gdb_breakpoint_remove_all(CPUState *cs)
{
const AccelOpsClass *ops = cpus_get_accel();
if (ops->remove_all_breakpoints) {
ops->remove_all_breakpoints(cs);
}
}

29
gdbstub/trace-events Normal file
View File

@ -0,0 +1,29 @@
# See docs/devel/tracing.rst for syntax documentation.
# gdbstub.c
gdbstub_op_start(const char *device) "Starting gdbstub using device %s"
gdbstub_op_exiting(uint8_t code) "notifying exit with code=0x%02x"
gdbstub_op_continue(void) "Continuing all CPUs"
gdbstub_op_continue_cpu(int cpu_index) "Continuing CPU %d"
gdbstub_op_stepping(int cpu_index) "Stepping CPU %d"
gdbstub_op_extra_info(const char *info) "Thread extra info: %s"
gdbstub_hit_watchpoint(const char *type, int cpu_gdb_index, uint64_t vaddr) "Watchpoint hit, type=\"%s\" cpu=%d, vaddr=0x%" PRIx64 ""
gdbstub_hit_internal_error(void) "RUN_STATE_INTERNAL_ERROR"
gdbstub_hit_break(void) "RUN_STATE_DEBUG"
gdbstub_hit_paused(void) "RUN_STATE_PAUSED"
gdbstub_hit_shutdown(void) "RUN_STATE_SHUTDOWN"
gdbstub_hit_io_error(void) "RUN_STATE_IO_ERROR"
gdbstub_hit_watchdog(void) "RUN_STATE_WATCHDOG"
gdbstub_hit_unknown(int state) "Unknown run state=0x%x"
gdbstub_io_reply(const char *message) "Sent: %s"
gdbstub_io_binaryreply(size_t ofs, const char *line) "0x%04zx: %s"
gdbstub_io_command(const char *command) "Received: %s"
gdbstub_io_got_ack(void) "Got ACK"
gdbstub_io_got_unexpected(uint8_t ch) "Got 0x%02x when expecting ACK/NACK"
gdbstub_err_got_nack(void) "Got NACK, retransmitting"
gdbstub_err_garbage(uint8_t ch) "received garbage between packets: 0x%02x"
gdbstub_err_overrun(void) "command buffer overrun, dropping command"
gdbstub_err_invalid_repeat(uint8_t ch) "got invalid RLE count: 0x%02x"
gdbstub_err_invalid_rle(void) "got invalid RLE sequence"
gdbstub_err_checksum_invalid(uint8_t ch) "got invalid command checksum digit: 0x%02x"
gdbstub_err_checksum_incorrect(uint8_t expected, uint8_t got) "got command packet with incorrect checksum, expected=0x%02x, received=0x%02x"

1
gdbstub/trace.h Normal file
View File

@ -0,0 +1 @@
#include "trace/trace-gdbstub.h"

68
gdbstub/user.c Normal file
View File

@ -0,0 +1,68 @@
/*
* gdbstub user-mode helper routines.
*
* We know for user-mode we are using TCG so we can call stuff directly.
*
* Copyright (c) 2022 Linaro Ltd
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "qemu/osdep.h"
#include "exec/hwaddr.h"
#include "exec/gdbstub.h"
#include "hw/core/cpu.h"
#include "internals.h"
bool gdb_supports_guest_debug(void)
{
/* user-mode == TCG == supported */
return true;
}
int gdb_breakpoint_insert(CPUState *cs, int type, hwaddr addr, hwaddr len)
{
CPUState *cpu;
int err = 0;
switch (type) {
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
CPU_FOREACH(cpu) {
err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
if (err) {
break;
}
}
return err;
default:
/* user-mode doesn't support watchpoints */
return -ENOSYS;
}
}
int gdb_breakpoint_remove(CPUState *cs, int type, hwaddr addr, hwaddr len)
{
CPUState *cpu;
int err = 0;
switch (type) {
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
CPU_FOREACH(cpu) {
err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
if (err) {
break;
}
}
return err;
default:
/* user-mode doesn't support watchpoints */
return -ENOSYS;
}
}
void gdb_breakpoint_remove_all(CPUState *cs)
{
cpu_breakpoint_remove_all(cs, BP_GDB);
}

View File

@ -595,7 +595,7 @@ void hmp_info_via(Monitor *mon, const QDict *qdict)
if (hmp_handle_error(mon, err)) { if (hmp_handle_error(mon, err)) {
return; return;
} }
monitor_printf(mon, "%s", info->human_readable_text); monitor_puts(mon, info->human_readable_text);
} }
static const MemoryRegionOps mos6522_ops = { static const MemoryRegionOps mos6522_ops = {

View File

@ -31,6 +31,7 @@ void monitor_resume(Monitor *mon);
int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp); int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp); int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
int monitor_puts(Monitor *mon, const char *str);
int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
G_GNUC_PRINTF(2, 0); G_GNUC_PRINTF(2, 0);
int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3); int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);

View File

@ -43,6 +43,10 @@ typedef struct AccelClass {
bool (*has_memory)(MachineState *ms, AddressSpace *as, bool (*has_memory)(MachineState *ms, AddressSpace *as,
hwaddr start_addr, hwaddr size); hwaddr start_addr, hwaddr size);
#endif #endif
/* gdbstub related hooks */
int (*gdbstub_supported_sstep_flags)(void);
bool *allowed; bool *allowed;
/* /*
* Array of global properties that would be applied when specific * Array of global properties that would be applied when specific
@ -92,4 +96,12 @@ void accel_cpu_instance_init(CPUState *cpu);
*/ */
bool accel_cpu_realizefn(CPUState *cpu, Error **errp); bool accel_cpu_realizefn(CPUState *cpu, Error **errp);
/**
* accel_supported_gdbstub_sstep_flags:
*
* Returns the supported single step modes for the configured
* accelerator.
*/
int accel_supported_gdbstub_sstep_flags(void);
#endif /* QEMU_ACCEL_H */ #endif /* QEMU_ACCEL_H */

View File

@ -224,6 +224,23 @@ void qemu_plugin_disable_mem_helpers(CPUState *cpu);
*/ */
void qemu_plugin_user_exit(void); void qemu_plugin_user_exit(void);
/**
* qemu_plugin_user_prefork_lock(): take plugin lock before forking
*
* This is a user-mode only helper to take the internal plugin lock
* before a fork event. This is ensure a consistent lock state
*/
void qemu_plugin_user_prefork_lock(void);
/**
* qemu_plugin_user_postfork(): reset the plugin lock
* @is_child: is this thread the child
*
* This user-mode only helper resets the lock state after a fork so we
* can continue using the plugin interface.
*/
void qemu_plugin_user_postfork(bool is_child);
#else /* !CONFIG_PLUGIN */ #else /* !CONFIG_PLUGIN */
static inline void qemu_plugin_add_opts(void) static inline void qemu_plugin_add_opts(void)
@ -287,6 +304,13 @@ static inline void qemu_plugin_disable_mem_helpers(CPUState *cpu)
static inline void qemu_plugin_user_exit(void) static inline void qemu_plugin_user_exit(void)
{ } { }
static inline void qemu_plugin_user_prefork_lock(void)
{ }
static inline void qemu_plugin_user_postfork(bool is_child)
{ }
#endif /* !CONFIG_PLUGIN */ #endif /* !CONFIG_PLUGIN */
#endif /* QEMU_PLUGIN_H */ #endif /* QEMU_PLUGIN_H */

View File

@ -10,6 +10,7 @@
#ifndef ACCEL_OPS_H #ifndef ACCEL_OPS_H
#define ACCEL_OPS_H #define ACCEL_OPS_H
#include "exec/hwaddr.h"
#include "qom/object.h" #include "qom/object.h"
#define ACCEL_OPS_SUFFIX "-ops" #define ACCEL_OPS_SUFFIX "-ops"
@ -44,6 +45,12 @@ struct AccelOpsClass {
int64_t (*get_virtual_clock)(void); int64_t (*get_virtual_clock)(void);
int64_t (*get_elapsed_ticks)(void); int64_t (*get_elapsed_ticks)(void);
/* gdbstub hooks */
bool (*supports_guest_debug)(void);
int (*insert_breakpoint)(CPUState *cpu, int type, hwaddr addr, hwaddr len);
int (*remove_breakpoint)(CPUState *cpu, int type, hwaddr addr, hwaddr len);
void (*remove_all_breakpoints)(CPUState *cpu);
}; };
#endif /* ACCEL_OPS_H */ #endif /* ACCEL_OPS_H */

View File

@ -7,6 +7,9 @@
/* register accel-specific operations */ /* register accel-specific operations */
void cpus_register_accel(const AccelOpsClass *i); void cpus_register_accel(const AccelOpsClass *i);
/* return registers ops */
const AccelOpsClass *cpus_get_accel(void);
/* accel/dummy-cpus.c */ /* accel/dummy-cpus.c */
/* Create a dummy vcpu for AccelOpsClass->create_vcpu_thread */ /* Create a dummy vcpu for AccelOpsClass->create_vcpu_thread */

View File

@ -46,8 +46,6 @@ extern bool kvm_readonly_mem_allowed;
extern bool kvm_direct_msi_allowed; extern bool kvm_direct_msi_allowed;
extern bool kvm_ioeventfd_any_length_allowed; extern bool kvm_ioeventfd_any_length_allowed;
extern bool kvm_msi_use_devid; extern bool kvm_msi_use_devid;
extern bool kvm_has_guest_debug;
extern int kvm_sstep_flags;
#define kvm_enabled() (kvm_allowed) #define kvm_enabled() (kvm_allowed)
/** /**
@ -169,17 +167,6 @@ extern int kvm_sstep_flags;
*/ */
#define kvm_msi_devid_required() (kvm_msi_use_devid) #define kvm_msi_devid_required() (kvm_msi_use_devid)
/*
* Does KVM support guest debugging
*/
#define kvm_supports_guest_debug() (kvm_has_guest_debug)
/*
* kvm_supported_sstep_flags
* Returns: SSTEP_* flags that KVM supports for guest debug
*/
#define kvm_get_supported_sstep_flags() (kvm_sstep_flags)
#else #else
#define kvm_enabled() (0) #define kvm_enabled() (0)
@ -197,8 +184,6 @@ extern int kvm_sstep_flags;
#define kvm_direct_msi_enabled() (false) #define kvm_direct_msi_enabled() (false)
#define kvm_ioeventfd_any_length_enabled() (false) #define kvm_ioeventfd_any_length_enabled() (false)
#define kvm_msi_devid_required() (false) #define kvm_msi_devid_required() (false)
#define kvm_supports_guest_debug() (false)
#define kvm_get_supported_sstep_flags() (0)
#endif /* CONFIG_KVM_IS_POSSIBLE */ #endif /* CONFIG_KVM_IS_POSSIBLE */
@ -262,12 +247,23 @@ int kvm_on_sigbus(int code, void *addr);
void kvm_flush_coalesced_mmio_buffer(void); void kvm_flush_coalesced_mmio_buffer(void);
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, /**
target_ulong len, int type); * kvm_update_guest_debug(): ensure KVM debug structures updated
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, * @cs: the CPUState for this cpu
target_ulong len, int type); * @reinject_trap: KVM trap injection control
void kvm_remove_all_breakpoints(CPUState *cpu); *
* There are usually per-arch specifics which will be handled by
* calling down to kvm_arch_update_guest_debug after the generic
* fields have been set.
*/
#ifdef KVM_CAP_SET_GUEST_DEBUG
int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap); int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap);
#else
static inline int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap)
{
return -EINVAL;
}
#endif
/* internal API */ /* internal API */

View File

@ -142,10 +142,12 @@ void fork_start(void)
start_exclusive(); start_exclusive();
mmap_fork_start(); mmap_fork_start();
cpu_list_lock(); cpu_list_lock();
qemu_plugin_user_prefork_lock();
} }
void fork_end(int child) void fork_end(int child)
{ {
qemu_plugin_user_postfork(child);
mmap_fork_end(child); mmap_fork_end(child);
if (child) { if (child) {
CPUState *cpu, *next_cpu; CPUState *cpu, *next_cpu;

View File

@ -2863,6 +2863,7 @@ trace_events_subdirs = [
'qom', 'qom',
'monitor', 'monitor',
'util', 'util',
'gdbstub',
] ]
if have_linux_user if have_linux_user
trace_events_subdirs += [ 'linux-user' ] trace_events_subdirs += [ 'linux-user' ]
@ -2986,6 +2987,7 @@ subdir('authz')
subdir('crypto') subdir('crypto')
subdir('ui') subdir('ui')
subdir('hw') subdir('hw')
subdir('gdbstub')
if enable_modules if enable_modules
@ -3063,7 +3065,7 @@ common_ss.add(files('cpus-common.c'))
subdir('softmmu') subdir('softmmu')
common_ss.add(capstone) common_ss.add(capstone)
specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone) specific_ss.add(files('cpu.c', 'disas.c'), capstone)
# Work around a gcc bug/misfeature wherein constant propagation looks # Work around a gcc bug/misfeature wherein constant propagation looks
# through an alias: # through an alias:
@ -3764,7 +3766,7 @@ summary(summary_info, bool_yn: true, section: 'Compilation')
summary_info = {} summary_info = {}
have_cross = false have_cross = false
foreach target: target_dirs foreach target: target_dirs
tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak' tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
if fs.exists(tcg_mak) if fs.exists(tcg_mak)
config_cross_tcg = keyval.load(tcg_mak) config_cross_tcg = keyval.load(tcg_mak)
if 'CC' in config_cross_tcg if 'CC' in config_cross_tcg

View File

@ -730,7 +730,7 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
monitor_printf(mon, " "); monitor_printf(mon, " ");
if (dev->class_info->has_desc) { if (dev->class_info->has_desc) {
monitor_printf(mon, "%s", dev->class_info->desc); monitor_puts(mon, dev->class_info->desc);
} else { } else {
monitor_printf(mon, "Class %04" PRId64, dev->class_info->q_class); monitor_printf(mon, "Class %04" PRId64, dev->class_info->q_class);
} }
@ -2258,12 +2258,12 @@ static void print_stats_schema_value(Monitor *mon, StatsSchemaValue *value)
if (unit && value->base == 10 && if (unit && value->base == 10 &&
value->exponent >= -18 && value->exponent <= 18 && value->exponent >= -18 && value->exponent <= 18 &&
value->exponent % 3 == 0) { value->exponent % 3 == 0) {
monitor_printf(mon, "%s", si_prefix(value->exponent)); monitor_puts(mon, si_prefix(value->exponent));
} else if (unit && value->base == 2 && } else if (unit && value->base == 2 &&
value->exponent >= 0 && value->exponent <= 60 && value->exponent >= 0 && value->exponent <= 60 &&
value->exponent % 10 == 0) { value->exponent % 10 == 0) {
monitor_printf(mon, "%s", iec_binary_prefix(value->exponent)); monitor_puts(mon, iec_binary_prefix(value->exponent));
} else if (value->exponent) { } else if (value->exponent) {
/* Use exponential notation and write the unit's English name */ /* Use exponential notation and write the unit's English name */
monitor_printf(mon, "* %d^%d%s", monitor_printf(mon, "* %d^%d%s",
@ -2273,7 +2273,7 @@ static void print_stats_schema_value(Monitor *mon, StatsSchemaValue *value)
} }
if (value->has_unit) { if (value->has_unit) {
monitor_printf(mon, "%s", unit ? unit : StatsUnit_str(value->unit)); monitor_puts(mon, unit ? unit : StatsUnit_str(value->unit));
} }
/* Print bucket size for linear histograms */ /* Print bucket size for linear histograms */

View File

@ -1094,7 +1094,7 @@ static void hmp_info_human_readable_text(Monitor *mon,
return; return;
} }
monitor_printf(mon, "%s", info->human_readable_text); monitor_puts(mon, info->human_readable_text);
} }
static void handle_hmp_command_exec(Monitor *mon, static void handle_hmp_command_exec(Monitor *mon,

View File

@ -174,7 +174,6 @@ extern int mon_refcount;
extern HMPCommand hmp_cmds[]; extern HMPCommand hmp_cmds[];
int monitor_puts(Monitor *mon, const char *str);
void monitor_data_init(Monitor *mon, bool is_qmp, bool skip_flush, void monitor_data_init(Monitor *mon, bool is_qmp, bool skip_flush,
bool use_io_thread); bool use_io_thread);
void monitor_data_destroy(Monitor *mon); void monitor_data_destroy(Monitor *mon);

View File

@ -8,49 +8,62 @@ all: multiboot.bin multiboot_dma.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bi
CFLAGS = -O2 -g CFLAGS = -O2 -g
quiet-command = $(if $(V),$1,$(if $(2),@printf " %-7s %s\n" $2 $3 && $1, @$1)) NULL :=
cc-option = $(if $(shell $(CC) $1 -c -o /dev/null -xc /dev/null >/dev/null 2>&1 && echo OK), $1, $2) SPACE := $(NULL) #
TARGET_PREFIX := $(patsubst %/,%:$(SPACE),$(TARGET_DIR))
override CFLAGS += -march=i486 -Wall $(EXTRA_CFLAGS) -m16 quiet-@ = $(if $(V),,@$(if $1,printf "%s\n" "$(TARGET_PREFIX)$1" && ))
quiet-command = $(call quiet-@,$2 $@)$1
# If -fcf-protection is enabled in flags or compiler defaults that will
# conflict with -march=i486
override CFLAGS += $(call cc-option, -fcf-protection=none)
# Flags for dependency generation # Flags for dependency generation
override CPPFLAGS += -MMD -MP -MT $@ -MF $(@D)/$(*F).d override CPPFLAGS += -MMD -MP -MT $@ -MF $(@D)/$(*F).d
override CFLAGS += $(call cc-option, -fno-pie) override CFLAGS += -march=i486 -Wall $(EXTRA_CFLAGS) -m16
override CFLAGS += $(call cc-option, -no-pie)
override CFLAGS += -ffreestanding -I$(TOPSRC_DIR)/include override CFLAGS += -ffreestanding -I$(TOPSRC_DIR)/include
override CFLAGS += $(call cc-option, -fno-stack-protector)
override CFLAGS += $(call cc-option, -Wno-array-bounds) cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null
cc-option = if $(call cc-test, $1); then \
echo "$(TARGET_PREFIX)$1 detected" && echo "override CFLAGS += $1" >&3; else \
echo "$(TARGET_PREFIX)$1 not detected" $(if $2,&& echo "override CFLAGS += $2" >&3); fi
# If -fcf-protection is enabled in flags or compiler defaults that will
# conflict with -march=i486
config-cc.mak: Makefile
$(quiet-@)($(call cc-option,-fcf-protection=none); \
$(call cc-option,-fno-pie); \
$(call cc-option,-no-pie); \
$(call cc-option,-fno-stack-protector); \
$(call cc-option,-Wno-array-bounds)) 3> config-cc.mak
-include config-cc.mak
override LDFLAGS = -nostdlib -Wl,-T,$(SRC_DIR)/flat.lds override LDFLAGS = -nostdlib -Wl,-T,$(SRC_DIR)/flat.lds
pvh.img: pvh.o pvh_main.o pvh.img: pvh.o pvh_main.o
%.o: %.S %.o: %.S
$(call quiet-command,$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<,"AS","$@") $(call quiet-command,$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<,Assembling)
%.o: %.c %.o: %.c
$(call quiet-command,$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@,"CC","$@") $(call quiet-command,$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@,Compiling)
%.img: %.o %.img: %.o
$(call quiet-command,$(CC) $(CFLAGS) $(LDFLAGS) -s -o $@ $^,"BUILD","$@") $(call quiet-command,$(CC) $(CFLAGS) $(LDFLAGS) -s -o $@ $^,Linking)
%.raw: %.img %.raw: %.img
$(call quiet-command,$(OBJCOPY) -O binary -j .text $< $@,"BUILD","$@") $(call quiet-command,$(OBJCOPY) -O binary -j .text $< $@,Extracting raw object)
%.bin: %.raw %.bin: %.raw
$(call quiet-command,$(PYTHON) $(TOPSRC_DIR)/scripts/signrom.py $< $@,"SIGN","$@") $(call quiet-command,$(PYTHON) $(TOPSRC_DIR)/scripts/signrom.py $< $@,Computing checksum into)
include $(wildcard *.d) include $(wildcard *.d)
clean: clean:
rm -f *.o *.d *.raw *.img *.bin *~ rm -f *.o *.d *.raw *.img *.bin *~
distclean:
rm -f config-cc.mak
# suppress auto-removal of intermediate files # suppress auto-removal of intermediate files
.SECONDARY: .SECONDARY:
.PHONY: all clean .PHONY: all clean distclean

View File

@ -6,9 +6,12 @@ include config-host.mak
CFLAGS = -O2 -g CFLAGS = -O2 -g
MAKEFLAGS += -rR MAKEFLAGS += -rR
quiet-command = $(if $(V),$1,$(if $(2),@printf " %-7s %s\n" $2 $3 && $1, @$1)) NULL :=
cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \ SPACE := $(NULL) #
>/dev/null 2>&1 && echo OK),$2,$3) TARGET_PREFIX := $(patsubst %/,%:$(SPACE),$(TARGET_DIR))
quiet-@ = $(if $(V),,@$(if $1,printf "%s\n" "$(TARGET_PREFIX)$1" && ))
quiet-command = $(call quiet-@,$2 $@)$1
VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.sh %.rc Kconfig% %.json.in VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.sh %.rc Kconfig% %.json.in
set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1))) set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1)))
@ -19,35 +22,46 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
%.o: %.c %.o: %.c
$(call quiet-command,$(CC) $(EXTRA_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) \ $(call quiet-command,$(CC) $(EXTRA_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) \
-c -o $@ $<,"CC","$(TARGET_DIR)$@") -c -o $@ $<,Compiling)
%.o: %.S %.o: %.S
$(call quiet-command,$(CCAS) $(EXTRA_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) \ $(call quiet-command,$(CCAS) $(EXTRA_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) \
-c -o $@ $<,"CCAS","$(TARGET_DIR)$@") -c -o $@ $<,Assembling)
.PHONY : all clean build-all .PHONY : all clean build-all distclean
OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \ OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o dasd-ipl.o virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o dasd-ipl.o
EXTRA_CFLAGS := $(EXTRA_CFLAGS) -Wall EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += $(call cc-option,-Werror $(EXTRA_CFLAGS),-Wno-stringop-overflow)
EXTRA_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -fno-common -fPIE EXTRA_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -fno-common -fPIE
EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables
EXTRA_CFLAGS += $(call cc-option, $(EXTRA_CFLAGS), -fno-stack-protector)
EXTRA_CFLAGS += $(call cc-option, $(EXTRA_CFLAGS), -Wno-array-bounds)
EXTRA_CFLAGS += -msoft-float EXTRA_CFLAGS += -msoft-float
EXTRA_CFLAGS += $(call cc-option, $(EXTRA_CFLAGS),-march=z900,-march=z10)
EXTRA_CFLAGS += -std=gnu99 EXTRA_CFLAGS += -std=gnu99
LDFLAGS += -Wl,-pie -nostdlib LDFLAGS += -Wl,-pie -nostdlib
cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null
cc-option = if $(call cc-test, $1); then \
echo "$(TARGET_PREFIX)$1 detected" && echo "EXTRA_CFLAGS += $1" >&3; else \
echo "$(TARGET_PREFIX)$1 not detected" $(if $2,&& echo "EXTRA_CFLAGS += $2" >&3); fi
config-cc.mak: Makefile
$(quiet-@)($(call cc-option,-Wno-stringop-overflow); \
$(call cc-option,-fno-stack-protector); \
$(call cc-option,-Wno-array-bounds); \
$(call cc-option,-Wno-gnu); \
$(call cc-option,-march=z900,-march=z10)) 3> config-cc.mak
-include config-cc.mak
LDFLAGS += -Wl,-pie -nostdlib
build-all: s390-ccw.img s390-netboot.img build-all: s390-ccw.img s390-netboot.img
s390-ccw.elf: $(OBJECTS) s390-ccw.elf: $(OBJECTS)
$(call quiet-command,$(CC) $(LDFLAGS) -o $@ $(OBJECTS),"BUILD","$(TARGET_DIR)$@") $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $(OBJECTS),Linking)
s390-ccw.img: s390-ccw.elf s390-ccw.img: s390-ccw.elf
$(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,"STRIP","$(TARGET_DIR)$@") $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into)
$(OBJECTS): Makefile $(OBJECTS): Makefile
@ -63,3 +77,6 @@ ALL_OBJS = $(sort $(OBJECTS) $(NETOBJS) $(LIBCOBJS) $(LIBNETOBJS))
clean: clean:
rm -f *.o *.d *.img *.elf *~ *.a rm -f *.o *.d *.img *.elf *~ *.a
distclean:
rm -f config-cc.mak

View File

@ -11,55 +11,52 @@ NETLDFLAGS := $(LDFLAGS) -Wl,-Ttext=0x7800000
$(NETOBJS): EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC) $(NETOBJS): EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC)
s390-netboot.elf: $(NETOBJS) libnet.a libc.a s390-netboot.elf: $(NETOBJS) libnet.a libc.a
$(call quiet-command,$(CC) $(NETLDFLAGS) -o $@ $^,"BUILD","$(TARGET_DIR)$@") $(call quiet-command,$(CC) $(NETLDFLAGS) -o $@ $^,Linking)
s390-netboot.img: s390-netboot.elf s390-netboot.img: s390-netboot.elf
$(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,"STRIP","$(TARGET_DIR)$@") $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into)
# SLOF is GCC-only, so ignore warnings about GNU extensions with Clang here
NO_GNU_WARN := $(call cc-option,-Werror $(QEMU_CFLAGS),-Wno-gnu)
# libc files: # libc files:
LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(NO_GNU_WARN) $(LIBC_INC) $(LIBNET_INC) \ LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \
-MMD -MP -MT $@ -MF $(@:%.o=%.d) -MMD -MP -MT $@ -MF $(@:%.o=%.d)
CTYPE_OBJS = isdigit.o isxdigit.o toupper.o CTYPE_OBJS = isdigit.o isxdigit.o toupper.o
%.o : $(SLOF_DIR)/lib/libc/ctype/%.c %.o : $(SLOF_DIR)/lib/libc/ctype/%.c
$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
STRING_OBJS = strcat.o strchr.o strrchr.o strcpy.o strlen.o strncpy.o \ STRING_OBJS = strcat.o strchr.o strrchr.o strcpy.o strlen.o strncpy.o \
strcmp.o strncmp.o strcasecmp.o strncasecmp.o strstr.o \ strcmp.o strncmp.o strcasecmp.o strncasecmp.o strstr.o \
memset.o memcpy.o memmove.o memcmp.o memset.o memcpy.o memmove.o memcmp.o
%.o : $(SLOF_DIR)/lib/libc/string/%.c %.o : $(SLOF_DIR)/lib/libc/string/%.c
$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
STDLIB_OBJS = atoi.o atol.o strtoul.o strtol.o rand.o malloc.o free.o STDLIB_OBJS = atoi.o atol.o strtoul.o strtol.o rand.o malloc.o free.o
%.o : $(SLOF_DIR)/lib/libc/stdlib/%.c %.o : $(SLOF_DIR)/lib/libc/stdlib/%.c
$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
STDIO_OBJS = sprintf.o snprintf.o vfprintf.o vsnprintf.o vsprintf.o fprintf.o \ STDIO_OBJS = sprintf.o snprintf.o vfprintf.o vsnprintf.o vsprintf.o fprintf.o \
printf.o putc.o puts.o putchar.o stdchnls.o fileno.o printf.o putc.o puts.o putchar.o stdchnls.o fileno.o
%.o : $(SLOF_DIR)/lib/libc/stdio/%.c %.o : $(SLOF_DIR)/lib/libc/stdio/%.c
$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
sbrk.o: $(SLOF_DIR)/slof/sbrk.c sbrk.o: $(SLOF_DIR)/slof/sbrk.c
$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
LIBCOBJS := $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) sbrk.o LIBCOBJS := $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) sbrk.o
libc.a: $(LIBCOBJS) libc.a: $(LIBCOBJS)
$(call quiet-command,$(AR) -rc $@ $^,"AR","$(TARGET_DIR)$@") $(call quiet-command,$(AR) -rc $@ $^,Creating static library)
# libnet files: # libnet files:
LIBNETOBJS := args.o dhcp.o dns.o icmpv6.o ipv6.o tcp.o udp.o bootp.o \ LIBNETOBJS := args.o dhcp.o dns.o icmpv6.o ipv6.o tcp.o udp.o bootp.o \
dhcpv6.o ethernet.o ipv4.o ndp.o tftp.o pxelinux.o dhcpv6.o ethernet.o ipv4.o ndp.o tftp.o pxelinux.o
LIBNETCFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(NO_GNU_WARN) $(LIBC_INC) $(LIBNET_INC) \ LIBNETCFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \
-DDHCPARCH=0x1F -MMD -MP -MT $@ -MF $(@:%.o=%.d) -DDHCPARCH=0x1F -MMD -MP -MT $@ -MF $(@:%.o=%.d)
%.o : $(SLOF_DIR)/lib/libnet/%.c %.o : $(SLOF_DIR)/lib/libnet/%.c
$(call quiet-command,$(CC) $(LIBNETCFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@") $(call quiet-command,$(CC) $(LIBNETCFLAGS) -c -o $@ $<,Compiling)
libnet.a: $(LIBNETOBJS) libnet.a: $(LIBNETOBJS)
$(call quiet-command,$(AR) -rc $@ $^,"AR","$(TARGET_DIR)$@") $(call quiet-command,$(AR) -rc $@ $^,Creating static library)

View File

@ -2,21 +2,30 @@ include config.mak
VPATH=$(SRC_DIR) VPATH=$(SRC_DIR)
all: vof.bin all: vof.bin
NULL :=
SPACE := $(NULL) #
TARGET_PREFIX := $(patsubst %/,%:$(SPACE),$(TARGET_DIR))
quiet-@ = $(if $(V),,@$(if $1,,printf "%s\n" "$(TARGET_PREFIX)$1" && ))
quiet-command = $(call quiet-@,$2 $@)$1
EXTRA_CFLAGS += -mcpu=power4 EXTRA_CFLAGS += -mcpu=power4
%.o: %.S %.o: %.S
$(CC) $(EXTRA_CFLAGS) -c -o $@ $< $(call quiet-command, $(CC) $(EXTRA_CFLAGS) -c -o $@ $<,Assembling)
%.o: %.c %.o: %.c
$(CC) $(EXTRA_CFLAGS) -c -fno-stack-protector -o $@ $< $(call quiet-command, $(CC) $(EXTRA_CFLAGS) -c -fno-stack-protector -o $@ $<,Compiling)
vof.elf: entry.o main.o ci.o bootmem.o libc.o vof.elf: entry.o main.o ci.o bootmem.o libc.o
$(LD) -nostdlib -e_start -T$(SRC_DIR)/vof.lds -EB -o $@ $^ $(call quiet-command, $(LD) -nostdlib -e_start -T$(SRC_DIR)/vof.lds -EB -o $@ $^,Linking)
%.bin: %.elf %.bin: %.elf
$(OBJCOPY) -O binary -j .text -j .data -j .toc -j .got2 $^ $@ $(call quiet-command, $(OBJCOPY) -O binary -j .text -j .data -j .toc -j .got2 $^ $@,Extracting raw object)
clean: clean:
rm -f *.o vof.bin vof.elf *~ rm -f *.o vof.bin vof.elf *~
.PHONY: all clean distclean: clean
.PHONY: all clean distclean

View File

@ -289,6 +289,8 @@ struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info); enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info);
hwaddr_info.is_store = (rw & QEMU_PLUGIN_MEM_W) != 0; hwaddr_info.is_store = (rw & QEMU_PLUGIN_MEM_W) != 0;
assert(mmu_idx < NB_MMU_MODES);
if (!tlb_plugin_lookup(cpu, vaddr, mmu_idx, if (!tlb_plugin_lookup(cpu, vaddr, mmu_idx,
hwaddr_info.is_store, &hwaddr_info)) { hwaddr_info.is_store, &hwaddr_info)) {
error_report("invalid use of qemu_plugin_get_hwaddr"); error_report("invalid use of qemu_plugin_get_hwaddr");

View File

@ -526,6 +526,26 @@ void qemu_plugin_user_exit(void)
qemu_plugin_atexit_cb(); qemu_plugin_atexit_cb();
} }
/*
* Helpers for *-user to ensure locks are sane across fork() events.
*/
void qemu_plugin_user_prefork_lock(void)
{
qemu_rec_mutex_lock(&plugin.lock);
}
void qemu_plugin_user_postfork(bool is_child)
{
if (is_child) {
/* should we just reset via plugin_init? */
qemu_rec_mutex_init(&plugin.lock);
} else {
qemu_rec_mutex_unlock(&plugin.lock);
}
}
/* /*
* Call this function after longjmp'ing to the main loop. It's possible that the * Call this function after longjmp'ing to the main loop. It's possible that the
* last instruction of a TB might have used helpers, and therefore the * last instruction of a TB might have used helpers, and therefore the

View File

@ -97,7 +97,7 @@
state: present state: present
when: when:
- ansible_facts['distribution'] == 'Ubuntu' - ansible_facts['distribution'] == 'Ubuntu'
- ansible_facts['architecture'] != 's390x' - ansible_facts['architecture'] == 'aarch64' or ansible_facts['architecture'] == 'x86_64'
- name: Install basic packages to build QEMU on Ubuntu 20.04 - name: Install basic packages to build QEMU on Ubuntu 20.04
package: package:
@ -153,13 +153,13 @@
- make - make
- mesa-libEGL-devel - mesa-libEGL-devel
- nettle-devel - nettle-devel
- ninja-build
- nmap-ncat - nmap-ncat
- perl-Test-Harness - perl-Test-Harness
- pixman-devel - pixman-devel
- python36 - python36
- rdma-core-devel - rdma-core-devel
- spice-glib-devel - spice-glib-devel
- spice-server
- systemtap-sdt-devel - systemtap-sdt-devel
- tar - tar
- zlib-devel - zlib-devel
@ -167,3 +167,14 @@
when: when:
- ansible_facts['distribution_file_variety'] == 'RedHat' - ansible_facts['distribution_file_variety'] == 'RedHat'
- ansible_facts['distribution_version'] == '8' - ansible_facts['distribution_version'] == '8'
- name: Install packages only available on x86 and aarch64
dnf:
# Spice server not available in ppc64le
name:
- spice-server
state: present
when:
- ansible_facts['distribution_file_variety'] == 'RedHat'
- ansible_facts['distribution_version'] == '8'
- ansible_facts['architecture'] == 'aarch64' or ansible_facts['architecture'] == 'x86_64'

View File

@ -24,7 +24,7 @@
* *
* ARM Semihosting is documented in: * ARM Semihosting is documented in:
* Semihosting for AArch32 and AArch64 Release 2.0 * Semihosting for AArch32 and AArch64 Release 2.0
* https://static.docs.arm.com/100863/0200/semihosting.pdf * https://github.com/ARM-software/abi-aa/blob/main/semihosting/semihosting.rst
* *
* RISC-V Semihosting is documented in: * RISC-V Semihosting is documented in:
* RISC-V Semihosting * RISC-V Semihosting

View File

@ -617,6 +617,13 @@ void cpus_register_accel(const AccelOpsClass *ops)
cpus_accel = ops; cpus_accel = ops;
} }
const AccelOpsClass *cpus_get_accel(void)
{
/* broken if we call this early */
assert(cpus_accel);
return cpus_accel;
}
void qemu_init_vcpu(CPUState *cpu) void qemu_init_vcpu(CPUState *cpu)
{ {
MachineState *ms = MACHINE(qdev_get_machine()); MachineState *ms = MACHINE(qdev_get_machine());

View File

@ -415,7 +415,7 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
if (need_reset) { if (need_reset) {
emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar, emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
recursive); recursive);
monitor_printf(params->mon, "%s", msg); monitor_puts(params->mon, msg);
qemu_log_mask(CPU_LOG_RESET, "%s\n", msg); qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
return; return;

View File

@ -36,12 +36,10 @@ export SRC_PATH
SPEED = quick SPEED = quick
-include tests/tcg/Makefile.prereqs
tests/tcg/Makefile.prereqs: config-host.mak
# Per guest TCG tests # Per guest TCG tests
BUILD_TCG_TARGET_RULES=$(patsubst %,build-tcg-tests-%, $(TCG_TESTS_TARGETS)) BUILD_TCG_TARGET_RULES=$(patsubst %,build-tcg-tests-%, $(TCG_TESTS_TARGETS))
CLEAN_TCG_TARGET_RULES=$(patsubst %,clean-tcg-tests-%, $(TCG_TESTS_TARGETS)) CLEAN_TCG_TARGET_RULES=$(patsubst %,clean-tcg-tests-%, $(TCG_TESTS_TARGETS))
DISTCLEAN_TCG_TARGET_RULES=$(patsubst %,distclean-tcg-tests-%, $(TCG_TESTS_TARGETS))
RUN_TCG_TARGET_RULES=$(patsubst %,run-tcg-tests-%, $(TCG_TESTS_TARGETS)) RUN_TCG_TARGET_RULES=$(patsubst %,run-tcg-tests-%, $(TCG_TESTS_TARGETS))
$(foreach TARGET,$(TCG_TESTS_TARGETS), \ $(foreach TARGET,$(TCG_TESTS_TARGETS), \
@ -50,23 +48,25 @@ $(foreach TARGET,$(TCG_TESTS_TARGETS), \
.PHONY: $(TCG_TESTS_TARGETS:%=build-tcg-tests-%) .PHONY: $(TCG_TESTS_TARGETS:%=build-tcg-tests-%)
$(TCG_TESTS_TARGETS:%=build-tcg-tests-%): build-tcg-tests-%: $(BUILD_DIR)/tests/tcg/config-%.mak $(TCG_TESTS_TARGETS:%=build-tcg-tests-%): build-tcg-tests-%: $(BUILD_DIR)/tests/tcg/config-%.mak
$(call quiet-command, \ $(call quiet-command, \
$(MAKE) -C tests/tcg/$* -f ../Makefile.target $(SUBDIR_MAKEFLAGS) \ $(MAKE) -C tests/tcg/$* $(SUBDIR_MAKEFLAGS), \
DOCKER_SCRIPT="$(DOCKER_SCRIPT)" \
TARGET="$*" SRC_PATH="$(SRC_PATH)", \
"BUILD","$* guest-tests") "BUILD","$* guest-tests")
.PHONY: $(TCG_TESTS_TARGETS:%=run-tcg-tests-%) .PHONY: $(TCG_TESTS_TARGETS:%=run-tcg-tests-%)
$(TCG_TESTS_TARGETS:%=run-tcg-tests-%): run-tcg-tests-%: build-tcg-tests-% $(TCG_TESTS_TARGETS:%=run-tcg-tests-%): run-tcg-tests-%: build-tcg-tests-%
$(call quiet-command, \ $(call quiet-command, \
$(MAKE) -C tests/tcg/$* -f ../Makefile.target $(SUBDIR_MAKEFLAGS) \ $(MAKE) -C tests/tcg/$* $(SUBDIR_MAKEFLAGS) SPEED=$(SPEED) run, \
TARGET="$*" SRC_PATH="$(SRC_PATH)" SPEED=$(SPEED) run, \
"RUN", "$* guest-tests") "RUN", "$* guest-tests")
.PHONY: $(TCG_TESTS_TARGETS:%=clean-tcg-tests-%) .PHONY: $(TCG_TESTS_TARGETS:%=clean-tcg-tests-%)
$(TCG_TESTS_TARGETS:%=clean-tcg-tests-%): clean-tcg-tests-%: $(TCG_TESTS_TARGETS:%=clean-tcg-tests-%): clean-tcg-tests-%:
$(call quiet-command, \ $(call quiet-command, \
$(MAKE) -C tests/tcg/$* -f ../Makefile.target $(SUBDIR_MAKEFLAGS) \ $(MAKE) -C tests/tcg/$* $(SUBDIR_MAKEFLAGS) clean, \
TARGET="$*" SRC_PATH="$(SRC_PATH)" clean, \ "CLEAN", "$* guest-tests")
.PHONY: $(TCG_TESTS_TARGETS:%=distclean-tcg-tests-%)
$(TCG_TESTS_TARGETS:%=distclean-tcg-tests-%): distclean-tcg-tests-%:
$(call quiet-command, \
$(MAKE) -C tests/tcg/$* $(SUBDIR_MAKEFLAGS) distclean, \
"CLEAN", "$* guest-tests") "CLEAN", "$* guest-tests")
.PHONY: build-tcg .PHONY: build-tcg
@ -79,6 +79,9 @@ check-tcg: $(RUN_TCG_TARGET_RULES)
.PHONY: clean-tcg .PHONY: clean-tcg
clean-tcg: $(CLEAN_TCG_TARGET_RULES) clean-tcg: $(CLEAN_TCG_TARGET_RULES)
.PHONY: distclean-tcg
distclean-tcg: $(DISTCLEAN_TCG_TARGET_RULES)
# Python venv for running tests # Python venv for running tests
.PHONY: check-venv check-avocado check-acceptance check-acceptance-deprecated-warning .PHONY: check-venv check-avocado check-acceptance check-acceptance-deprecated-warning
@ -163,5 +166,6 @@ check-clean:
rm -rf $(TESTS_VENV_DIR) $(TESTS_RESULTS_DIR) rm -rf $(TESTS_VENV_DIR) $(TESTS_RESULTS_DIR)
clean: check-clean clean-tcg clean: check-clean clean-tcg
distclean: distclean-tcg
endif endif

View File

@ -14,7 +14,7 @@ DOCKER_DEFAULT_REGISTRY := registry.gitlab.com/qemu-project/qemu
endif endif
DOCKER_REGISTRY := $(if $(REGISTRY),$(REGISTRY),$(DOCKER_DEFAULT_REGISTRY)) DOCKER_REGISTRY := $(if $(REGISTRY),$(REGISTRY),$(DOCKER_DEFAULT_REGISTRY))
ENGINE := auto ENGINE ?= auto
DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py --engine $(ENGINE) DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py --engine $(ENGINE)
CUR_TIME := $(shell date +%Y-%m-%d-%H.%M.%S.$$$$) CUR_TIME := $(shell date +%Y-%m-%d-%H.%M.%S.$$$$)

View File

@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED # THIS FILE WAS AUTO-GENERATED
# #
# $ lcitool dockerfile --layers all alpine-edge qemu # $ lcitool dockerfile --layers all alpine-316 qemu
# #
# https://gitlab.com/libvirt/libvirt-ci # https://gitlab.com/libvirt/libvirt-ci
FROM docker.io/library/alpine:edge FROM docker.io/library/alpine:3.16
RUN apk update && \ RUN apk update && \
apk upgrade && \ apk upgrade && \
@ -13,6 +13,7 @@ RUN apk update && \
attr-dev \ attr-dev \
bash \ bash \
bc \ bc \
bison \
bzip2 \ bzip2 \
bzip2-dev \ bzip2-dev \
ca-certificates \ ca-certificates \
@ -30,6 +31,7 @@ RUN apk update && \
dtc-dev \ dtc-dev \
eudev-dev \ eudev-dev \
findutils \ findutils \
flex \
fuse3-dev \ fuse3-dev \
g++ \ g++ \
gcc \ gcc \

View File

@ -17,6 +17,7 @@ RUN dnf distro-sync -y && \
alsa-lib-devel \ alsa-lib-devel \
bash \ bash \
bc \ bc \
bison \
brlapi-devel \ brlapi-devel \
bzip2 \ bzip2 \
bzip2-devel \ bzip2-devel \
@ -31,6 +32,7 @@ RUN dnf distro-sync -y && \
device-mapper-multipath-devel \ device-mapper-multipath-devel \
diffutils \ diffutils \
findutils \ findutils \
flex \
fuse3-devel \ fuse3-devel \
gcc \ gcc \
gcc-c++ \ gcc-c++ \

View File

@ -13,6 +13,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \ eatmydata apt-get install --no-install-recommends -y \
bash \ bash \
bc \ bc \
bison \
bsdextrautils \ bsdextrautils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -22,11 +23,13 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
diffutils \ diffutils \
exuberant-ctags \ exuberant-ctags \
findutils \ findutils \
flex \
gcovr \ gcovr \
genisoimage \ genisoimage \
gettext \ gettext \
git \ git \
hostname \ hostname \
libglib2.0-dev \
libpcre2-dev \ libpcre2-dev \
libspice-protocol-dev \ libspice-protocol-dev \
llvm \ llvm \

View File

@ -13,6 +13,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \ eatmydata apt-get install --no-install-recommends -y \
bash \ bash \
bc \ bc \
bison \
bsdextrautils \ bsdextrautils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -23,6 +24,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
diffutils \ diffutils \
exuberant-ctags \ exuberant-ctags \
findutils \ findutils \
flex \
g++ \ g++ \
gcc \ gcc \
gcovr \ gcovr \

View File

@ -13,6 +13,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \ eatmydata apt-get install --no-install-recommends -y \
bash \ bash \
bc \ bc \
bison \
bsdextrautils \ bsdextrautils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -22,11 +23,13 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
diffutils \ diffutils \
exuberant-ctags \ exuberant-ctags \
findutils \ findutils \
flex \
gcovr \ gcovr \
genisoimage \ genisoimage \
gettext \ gettext \
git \ git \
hostname \ hostname \
libglib2.0-dev \
libpcre2-dev \ libpcre2-dev \
libspice-protocol-dev \ libspice-protocol-dev \
llvm \ llvm \

View File

@ -13,6 +13,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \ eatmydata apt-get install --no-install-recommends -y \
bash \ bash \
bc \ bc \
bison \
bsdextrautils \ bsdextrautils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -22,11 +23,13 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
diffutils \ diffutils \
exuberant-ctags \ exuberant-ctags \
findutils \ findutils \
flex \
gcovr \ gcovr \
genisoimage \ genisoimage \
gettext \ gettext \
git \ git \
hostname \ hostname \
libglib2.0-dev \
libpcre2-dev \ libpcre2-dev \
libspice-protocol-dev \ libspice-protocol-dev \
llvm \ llvm \

View File

@ -13,6 +13,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \ eatmydata apt-get install --no-install-recommends -y \
bash \ bash \
bc \ bc \
bison \
bsdextrautils \ bsdextrautils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -22,11 +23,13 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
diffutils \ diffutils \
exuberant-ctags \ exuberant-ctags \
findutils \ findutils \
flex \
gcovr \ gcovr \
genisoimage \ genisoimage \
gettext \ gettext \
git \ git \
hostname \ hostname \
libglib2.0-dev \
libpcre2-dev \ libpcre2-dev \
libspice-protocol-dev \ libspice-protocol-dev \
llvm \ llvm \

View File

@ -13,6 +13,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \ eatmydata apt-get install --no-install-recommends -y \
bash \ bash \
bc \ bc \
bison \
bsdextrautils \ bsdextrautils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -22,11 +23,13 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
diffutils \ diffutils \
exuberant-ctags \ exuberant-ctags \
findutils \ findutils \
flex \
gcovr \ gcovr \
genisoimage \ genisoimage \
gettext \ gettext \
git \ git \
hostname \ hostname \
libglib2.0-dev \
libpcre2-dev \ libpcre2-dev \
libspice-protocol-dev \ libspice-protocol-dev \
llvm \ llvm \

View File

@ -13,6 +13,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \ eatmydata apt-get install --no-install-recommends -y \
bash \ bash \
bc \ bc \
bison \
bsdextrautils \ bsdextrautils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -22,11 +23,13 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
diffutils \ diffutils \
exuberant-ctags \ exuberant-ctags \
findutils \ findutils \
flex \
gcovr \ gcovr \
genisoimage \ genisoimage \
gettext \ gettext \
git \ git \
hostname \ hostname \
libglib2.0-dev \
libpcre2-dev \ libpcre2-dev \
libspice-protocol-dev \ libspice-protocol-dev \
llvm \ llvm \

View File

@ -13,6 +13,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \ eatmydata apt-get install --no-install-recommends -y \
bash \ bash \
bc \ bc \
bison \
bsdextrautils \ bsdextrautils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -22,11 +23,13 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
diffutils \ diffutils \
exuberant-ctags \ exuberant-ctags \
findutils \ findutils \
flex \
gcovr \ gcovr \
genisoimage \ genisoimage \
gettext \ gettext \
git \ git \
hostname \ hostname \
libglib2.0-dev \
libpcre2-dev \ libpcre2-dev \
libspice-protocol-dev \ libspice-protocol-dev \
llvm \ llvm \

View File

@ -16,13 +16,16 @@ RUN apt update && \
# Install common build utilities # Install common build utilities
RUN DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy \ RUN DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy \
bison \
bc \ bc \
build-essential \ build-essential \
ca-certificates \ ca-certificates \
debian-ports-archive-keyring \ debian-ports-archive-keyring \
dpkg-dev \ dpkg-dev \
flex \
gettext \ gettext \
git \ git \
libglib2.0-dev \
ninja-build \ ninja-build \
pkg-config \ pkg-config \
python3 python3

View File

@ -13,6 +13,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \ eatmydata apt-get install --no-install-recommends -y \
bash \ bash \
bc \ bc \
bison \
bsdextrautils \ bsdextrautils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -22,11 +23,13 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
diffutils \ diffutils \
exuberant-ctags \ exuberant-ctags \
findutils \ findutils \
flex \
gcovr \ gcovr \
genisoimage \ genisoimage \
gettext \ gettext \
git \ git \
hostname \ hostname \
libglib2.0-dev \
libpcre2-dev \ libpcre2-dev \
libspice-protocol-dev \ libspice-protocol-dev \
llvm \ llvm \

View File

@ -1,9 +1,11 @@
FROM registry.fedoraproject.org/fedora:34 FROM registry.fedoraproject.org/fedora:34
ENV PACKAGES \ ENV PACKAGES \
bison \
bzip2 \ bzip2 \
ccache \ ccache \
diffutils \ diffutils \
flex \
findutils \ findutils \
gcc \ gcc \
git \ git \

View File

@ -3,13 +3,16 @@ FROM registry.fedoraproject.org/fedora:35
# Please keep this list sorted alphabetically # Please keep this list sorted alphabetically
ENV PACKAGES \ ENV PACKAGES \
bc \ bc \
bison \
bzip2 \ bzip2 \
ccache \ ccache \
diffutils \ diffutils \
findutils \ findutils \
flex \
gcc \ gcc \
gettext \ gettext \
git \ git \
glib2-devel \
hostname \ hostname \
make \ make \
meson \ meson \

View File

@ -3,13 +3,16 @@ FROM registry.fedoraproject.org/fedora:35
# Please keep this list sorted alphabetically # Please keep this list sorted alphabetically
ENV PACKAGES \ ENV PACKAGES \
bc \ bc \
bison \
bzip2 \ bzip2 \
ccache \ ccache \
diffutils \ diffutils \
findutils \ findutils \
flex \
gcc \ gcc \
gettext \ gettext \
git \ git \
glib2-devel \
hostname \ hostname \
make \ make \
meson \ meson \

View File

@ -23,6 +23,7 @@ exec "$@"' > /usr/bin/nosync && \
alsa-lib-devel \ alsa-lib-devel \
bash \ bash \
bc \ bc \
bison \
brlapi-devel \ brlapi-devel \
bzip2 \ bzip2 \
bzip2-devel \ bzip2-devel \
@ -37,6 +38,7 @@ exec "$@"' > /usr/bin/nosync && \
device-mapper-multipath-devel \ device-mapper-multipath-devel \
diffutils \ diffutils \
findutils \ findutils \
flex \
fuse3-devel \ fuse3-devel \
gcc \ gcc \
gcc-c++ \ gcc-c++ \

View File

@ -12,6 +12,7 @@ RUN zypper update -y && \
alsa-lib-devel \ alsa-lib-devel \
bash \ bash \
bc \ bc \
bison \
brlapi-devel \ brlapi-devel \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -22,6 +23,7 @@ RUN zypper update -y && \
dbus-1 \ dbus-1 \
diffutils \ diffutils \
findutils \ findutils \
flex \
fuse3-devel \ fuse3-devel \
gcc \ gcc \
gcc-c++ \ gcc-c++ \

View File

@ -13,6 +13,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \ eatmydata apt-get install --no-install-recommends -y \
bash \ bash \
bc \ bc \
bison \
bsdmainutils \ bsdmainutils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
@ -23,6 +24,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
diffutils \ diffutils \
exuberant-ctags \ exuberant-ctags \
findutils \ findutils \
flex \
g++ \ g++ \
gcc \ gcc \
gcovr \ gcovr \

View File

@ -15,7 +15,7 @@ if test -n "$V"; then
set -x set -x
fi fi
BASE="$(dirname $(readlink -e $0))" BASE="$(dirname $(realpath $0))"
# Prepare the environment # Prepare the environment
export PATH=/usr/lib/ccache:/usr/lib64/ccache:$PATH export PATH=/usr/lib/ccache:/usr/lib64/ccache:$PATH

View File

@ -3,6 +3,7 @@ packages:
- alsa - alsa
- bash - bash
- bc - bc
- bison
- brlapi - brlapi
- bzip2 - bzip2
- bzip2-libs - bzip2-libs
@ -19,6 +20,7 @@ packages:
- diffutils - diffutils
- dtrace - dtrace
- findutils - findutils
- flex
- fuse3 - fuse3
- g++ - g++
- gcc - gcc
@ -26,6 +28,7 @@ packages:
- gettext - gettext
- genisoimage - genisoimage
- glib2 - glib2
- glib2-native
- glib2-static - glib2-static
- glusterfs - glusterfs
- gnutls - gnutls

View File

@ -107,7 +107,7 @@ try:
# #
# Standard native builds # Standard native builds
# #
generate_dockerfile("alpine", "alpine-edge") generate_dockerfile("alpine", "alpine-316")
generate_dockerfile("centos8", "centos-stream-8") generate_dockerfile("centos8", "centos-stream-8")
generate_dockerfile("debian-amd64", "debian-11", generate_dockerfile("debian-amd64", "debian-11",
trailer="".join(debian11_extras)) trailer="".join(debian11_extras))

View File

@ -24,7 +24,7 @@
#include "libqos-malloc.h" #include "libqos-malloc.h"
/* maximum path length */ /* maximum path length */
#define QOS_PATH_MAX_ELEMENT_SIZE 50 #define QOS_PATH_MAX_ELEMENT_SIZE 64
typedef struct QOSGraphObject QOSGraphObject; typedef struct QOSGraphObject QOSGraphObject;
typedef struct QOSGraphNode QOSGraphNode; typedef struct QOSGraphNode QOSGraphNode;

View File

@ -31,7 +31,7 @@
all: all:
-include ../config-host.mak -include ../config-host.mak
-include ../config-$(TARGET).mak -include config-target.mak
# Get semihosting definitions for user-mode emulation # Get semihosting definitions for user-mode emulation
ifeq ($(filter %-softmmu, $(TARGET)),) ifeq ($(filter %-softmmu, $(TARGET)),)
@ -40,15 +40,25 @@ endif
# for including , in command strings # for including , in command strings
COMMA := , COMMA := ,
NULL :=
SPACE := $(NULL) #
TARGET_PREFIX=tests/tcg/$(TARGET):$(SPACE)
quiet-command = $(if $(V),$1,$(if $(2),@printf " %-7s %s\n" $2 $3 && $1, @$1)) quiet-@ = $(if $(V),,@$(if $1,printf " %-7s %s\n" "$(strip $1)" "$(strip $2)" && ))
quiet-command = $(call quiet-@,$2,$3)$1
cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>&1
cc-option = if $(call cc-test, $1); then \
echo "$(TARGET_PREFIX)$1 detected" && echo "$(strip $2)=y" >&3; else \
echo "$(TARGET_PREFIX)$1 not detected"; fi
# $1 = test name, $2 = cmd, $3 = desc # $1 = test name, $2 = cmd, $3 = desc
ifeq ($(filter %-softmmu, $(TARGET)),) ifeq ($(filter %-softmmu, $(TARGET)),)
run-test = $(call quiet-command, timeout --foreground $(TIMEOUT) $2 > $1.out, \ run-test = $(call quiet-command, timeout --foreground $(TIMEOUT) $2 > $1.out, \
"TEST",$3) TEST,$(or $3, $*, $<) on $(TARGET_NAME))
else else
run-test = $(call quiet-command, timeout --foreground $(TIMEOUT) $2,"TEST",$3) run-test = $(call quiet-command, timeout --foreground $(TIMEOUT) $2, \
TEST,$(or $3, $*, $<) on $(TARGET_NAME))
endif endif
# $1 = test name, $2 = reference # $1 = test name, $2 = reference
@ -56,7 +66,7 @@ endif
# we know it failed and then force failure at the end. # we know it failed and then force failure at the end.
diff-out = $(call quiet-command, diff -q $1.out $2 || \ diff-out = $(call quiet-command, diff -q $1.out $2 || \
(diff -u $1.out $2 | head -n 10 && false), \ (diff -u $1.out $2 | head -n 10 && false), \
"DIFF","$1.out with $2") DIFF,$1.out with $2)
# $1 = test name, $2 = reason # $1 = test name, $2 = reason
skip-test = @printf " SKIPPED %s on $(TARGET_NAME) because %s\n" $1 $2 skip-test = @printf " SKIPPED %s on $(TARGET_NAME) because %s\n" $1 $2
@ -155,21 +165,19 @@ RUN_TESTS+=$(EXTRA_RUNS)
ifeq ($(filter %-softmmu, $(TARGET)),) ifeq ($(filter %-softmmu, $(TARGET)),)
run-%: % run-%: %
$(call run-test, $<, $(QEMU) $(QEMU_OPTS) $<, "$< on $(TARGET_NAME)") $(call run-test, $<, $(QEMU) $(QEMU_OPTS) $<)
run-plugin-%: run-plugin-%:
$(call run-test, $@, $(QEMU) $(QEMU_OPTS) \ $(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
-plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \ -plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \
-d plugin -D $*.pout \ -d plugin -D $*.pout \
$(call strip-plugin,$<), \ $(call strip-plugin,$<))
"$* on $(TARGET_NAME)")
else else
run-%: % run-%: %
$(call run-test, $<, \ $(call run-test, $<, \
$(QEMU) -monitor none -display none \ $(QEMU) -monitor none -display none \
-chardev file$(COMMA)path=$<.out$(COMMA)id=output \ -chardev file$(COMMA)path=$<.out$(COMMA)id=output \
$(QEMU_OPTS) $<, \ $(QEMU_OPTS) $<)
"$< on $(TARGET_NAME)")
run-plugin-%: run-plugin-%:
$(call run-test, $@, \ $(call run-test, $@, \
@ -177,8 +185,7 @@ run-plugin-%:
-chardev file$(COMMA)path=$@.out$(COMMA)id=output \ -chardev file$(COMMA)path=$@.out$(COMMA)id=output \
-plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \ -plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \
-d plugin -D $*.pout \ -d plugin -D $*.pout \
$(QEMU_OPTS) $(call strip-plugin,$<), \ $(QEMU_OPTS) $(call strip-plugin,$<))
"$* on $(TARGET_NAME)")
endif endif
gdb-%: % gdb-%: %
@ -189,3 +196,6 @@ run: $(RUN_TESTS)
clean: clean:
rm -f $(TESTS) *.o $(CLEANFILES) rm -f $(TESTS) *.o $(CLEANFILES)
distclean:
rm -f config-cc.mak config-target.mak ../config-$(TARGET).mak

View File

@ -19,6 +19,11 @@ EXTRA_RUNS+=$(MULTIARCH_RUNS)
CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC) CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
config-cc.mak: Makefile
$(quiet-@)( \
$(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3)) 3> config-cc.mak
-include config-cc.mak
# building head blobs # building head blobs
.PRECIOUS: $(CRT_OBJS) .PRECIOUS: $(CRT_OBJS)
@ -50,8 +55,7 @@ run-memory-record: memory-record memory
$(QEMU) -monitor none -display none \ $(QEMU) -monitor none -display none \
-chardev file$(COMMA)path=$<.out$(COMMA)id=output \ -chardev file$(COMMA)path=$<.out$(COMMA)id=output \
-icount shift=5$(COMMA)rr=record$(COMMA)rrfile=record.bin \ -icount shift=5$(COMMA)rr=record$(COMMA)rrfile=record.bin \
$(QEMU_OPTS) memory, \ $(QEMU_OPTS) memory)
"$< on $(TARGET_NAME)")
.PHONY: memory-replay .PHONY: memory-replay
run-memory-replay: memory-replay run-memory-record run-memory-replay: memory-replay run-memory-record
@ -59,8 +63,7 @@ run-memory-replay: memory-replay run-memory-record
$(QEMU) -monitor none -display none \ $(QEMU) -monitor none -display none \
-chardev file$(COMMA)path=$<.out$(COMMA)id=output \ -chardev file$(COMMA)path=$<.out$(COMMA)id=output \
-icount shift=5$(COMMA)rr=replay$(COMMA)rrfile=record.bin \ -icount shift=5$(COMMA)rr=replay$(COMMA)rrfile=record.bin \
$(QEMU_OPTS) memory, \ $(QEMU_OPTS) memory)
"$< on $(TARGET_NAME)")
EXTRA_RUNS+=run-memory-replay EXTRA_RUNS+=run-memory-replay

View File

@ -17,6 +17,15 @@ run-fcvt: fcvt
$(call run-test,$<,$(QEMU) $<, "$< on $(TARGET_NAME)") $(call run-test,$<,$(QEMU) $<, "$< on $(TARGET_NAME)")
$(call diff-out,$<,$(AARCH64_SRC)/fcvt.ref) $(call diff-out,$<,$(AARCH64_SRC)/fcvt.ref)
config-cc.mak: Makefile
$(quiet-@)( \
$(call cc-option,-march=armv8.1-a+sve, CROSS_CC_HAS_SVE); \
$(call cc-option,-march=armv8.1-a+sve2, CROSS_CC_HAS_SVE2); \
$(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3); \
$(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
$(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE)) 3> config-cc.mak
-include config-cc.mak
# Pauth Tests # Pauth Tests
ifneq ($(CROSS_CC_HAS_ARMV8_3),) ifneq ($(CROSS_CC_HAS_ARMV8_3),)
AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5
@ -55,7 +64,7 @@ sha1-vector: CFLAGS=-O3
sha1-vector: sha1.c sha1-vector: sha1.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
run-sha1-vector: sha1-vector run-sha1 run-sha1-vector: sha1-vector run-sha1
$(call run-test, $<, $(QEMU) $(QEMU_OPTS) $<, "$< on $(TARGET_NAME)") $(call run-test, $<, $(QEMU) $(QEMU_OPTS) $<)
$(call diff-out, sha1-vector, sha1.out) $(call diff-out, sha1-vector, sha1.out)
TESTS += sha1-vector TESTS += sha1-vector
@ -75,14 +84,14 @@ run-gdbstub-sysregs: sysregs
--gdb $(HAVE_GDB_BIN) \ --gdb $(HAVE_GDB_BIN) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(AARCH64_SRC)/gdbstub/test-sve.py, \ --bin $< --test $(AARCH64_SRC)/gdbstub/test-sve.py, \
"basic gdbstub SVE support") basic gdbstub SVE support)
run-gdbstub-sve-ioctls: sve-ioctls run-gdbstub-sve-ioctls: sve-ioctls
$(call run-test, $@, $(GDB_SCRIPT) \ $(call run-test, $@, $(GDB_SCRIPT) \
--gdb $(HAVE_GDB_BIN) \ --gdb $(HAVE_GDB_BIN) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(AARCH64_SRC)/gdbstub/test-sve-ioctl.py, \ --bin $< --test $(AARCH64_SRC)/gdbstub/test-sve-ioctl.py, \
"basic gdbstub SVE ZLEN support") basic gdbstub SVE ZLEN support)
EXTRA_RUNS += run-gdbstub-sysregs run-gdbstub-sve-ioctls EXTRA_RUNS += run-gdbstub-sysregs run-gdbstub-sve-ioctls
endif endif

View File

@ -26,7 +26,7 @@ ARM_TESTS += fcvt
fcvt: LDFLAGS+=-lm fcvt: LDFLAGS+=-lm
# fcvt: CFLAGS+=-march=armv8.2-a+fp16 -mfpu=neon-fp-armv8 # fcvt: CFLAGS+=-march=armv8.2-a+fp16 -mfpu=neon-fp-armv8
run-fcvt: fcvt run-fcvt: fcvt
$(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)") $(call run-test,fcvt,$(QEMU) $<)
$(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref) $(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
# PC alignment test # PC alignment test
@ -44,13 +44,12 @@ semihosting-arm: semihosting.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
run-semihosting-arm: semihosting-arm run-semihosting-arm: semihosting-arm
$(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)") $(call run-test,$<,$(QEMU) $< 2> $<.err)
run-plugin-semihosting-arm-with-%: run-plugin-semihosting-arm-with-%:
$(call run-test, $@, $(QEMU) $(QEMU_OPTS) \ $(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
-plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \ -plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \
$(call strip-plugin,$<) 2> $<.err, \ $(call strip-plugin,$<) 2> $<.err)
"$< on $(TARGET_NAME) with $*")
ARM_TESTS += semiconsole-arm ARM_TESTS += semiconsole-arm
@ -75,7 +74,7 @@ sha1-vector: CFLAGS=-O3
sha1-vector: sha1.c sha1-vector: sha1.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
run-sha1-vector: sha1-vector run-sha1 run-sha1-vector: sha1-vector run-sha1
$(call run-test, $<, $(QEMU) $(QEMU_OPTS) $<, "$< on $(TARGET_NAME)") $(call run-test, $<, $(QEMU) $(QEMU_OPTS) $<)
$(call diff-out, sha1-vector, sha1.out) $(call diff-out, sha1-vector, sha1.out)
ARM_TESTS += sha1-vector ARM_TESTS += sha1-vector

View File

@ -56,4 +56,4 @@ SIMG:=cris-axis-linux-gnu-run
# e.g.: make -f ../../tests/tcg/Makefile run-check_orm-on-sim # e.g.: make -f ../../tests/tcg/Makefile run-check_orm-on-sim
run-%-on-sim: run-%-on-sim:
$(call run-test, $<, $(SIMG) $<, "$< on $(TARGET_NAME) with SIM") $(call run-test, $<, $(SIMG) $<)

View File

@ -40,8 +40,7 @@ run-plugin-%-with-libinsn.so:
-chardev file$(COMMA)path=$@.out$(COMMA)id=output \ -chardev file$(COMMA)path=$@.out$(COMMA)id=output \
-plugin ../../plugin/libinsn.so$(COMMA)inline=on \ -plugin ../../plugin/libinsn.so$(COMMA)inline=on \
-d plugin -D $*-with-libinsn.so.pout \ -d plugin -D $*-with-libinsn.so.pout \
$(QEMU_OPTS) $*, \ $(QEMU_OPTS) $*)
"$* on $(TARGET_NAME)")
# Running # Running
QEMU_OPTS+=-device isa-debugcon,chardev=output -device isa-debug-exit,iobase=0xf4,iosize=0x4 -kernel QEMU_OPTS+=-device isa-debugcon,chardev=output -device isa-debug-exit,iobase=0xf4,iosize=0x4 -kernel

View File

@ -5,6 +5,12 @@ I386_SRC=$(SRC_PATH)/tests/tcg/i386
# Set search path for all sources # Set search path for all sources
VPATH += $(I386_SRC) VPATH += $(I386_SRC)
config-cc.mak: Makefile
$(quiet-@)( \
$(call cc-option,-fno-pie, CROSS_CC_HAS_I386_NOPIE)) 3> config-cc.mak
-include config-cc.mak
I386_SRCS=$(notdir $(wildcard $(I386_SRC)/*.c)) I386_SRCS=$(notdir $(wildcard $(I386_SRC)/*.c))
ALL_X86_TESTS=$(I386_SRCS:.c=) ALL_X86_TESTS=$(I386_SRCS:.c=)
SKIP_I386_TESTS=test-i386-ssse3 test-avx test-3dnow test-mmx SKIP_I386_TESTS=test-i386-ssse3 test-avx test-3dnow test-mmx
@ -53,7 +59,7 @@ test-i386-fprem.ref: test-i386-fprem
run-test-i386-fprem: TIMEOUT=60 run-test-i386-fprem: TIMEOUT=60
run-test-i386-fprem: test-i386-fprem test-i386-fprem.ref run-test-i386-fprem: test-i386-fprem test-i386-fprem.ref
$(call run-test,test-i386-fprem, $(QEMU) $<,"$< on $(TARGET_NAME)") $(call run-test,test-i386-fprem, $(QEMU) $<)
$(call diff-out,test-i386-fprem, test-i386-fprem.ref) $(call diff-out,test-i386-fprem, test-i386-fprem.ref)
else else
SKIP_I386_TESTS+=test-i386-fprem SKIP_I386_TESTS+=test-i386-fprem
@ -63,8 +69,7 @@ endif
run-plugin-%-with-libinsn.so: run-plugin-%-with-libinsn.so:
$(call run-test, $@, $(QEMU) $(QEMU_OPTS) \ $(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
-plugin ../../plugin/libinsn.so$(COMMA)inline=on \ -plugin ../../plugin/libinsn.so$(COMMA)inline=on \
-d plugin -D $*-with-libinsn.so.pout $*, \ -d plugin -D $*-with-libinsn.so.pout $*)
"$* (inline) on $(TARGET_NAME)")
# Update TESTS # Update TESTS
I386_TESTS:=$(filter-out $(SKIP_I386_TESTS), $(ALL_X86_TESTS)) I386_TESTS:=$(filter-out $(SKIP_I386_TESTS), $(ALL_X86_TESTS))

View File

@ -26,7 +26,7 @@ float_%: float_%.c libs/float_helpers.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< $(MULTIARCH_SRC)/libs/float_helpers.c -o $@ $(LDFLAGS) $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< $(MULTIARCH_SRC)/libs/float_helpers.c -o $@ $(LDFLAGS)
run-float_%: float_% run-float_%: float_%
$(call run-test,$<, $(QEMU) $(QEMU_OPTS) $<,"$< on $(TARGET_NAME)") $(call run-test,$<, $(QEMU) $(QEMU_OPTS) $<)
$(call conditional-diff-out,$<,$(SRC_PATH)/tests/tcg/$(TARGET_NAME)/$<.ref) $(call conditional-diff-out,$<,$(SRC_PATH)/tests/tcg/$(TARGET_NAME)/$<.ref)
@ -42,13 +42,11 @@ signals: LDFLAGS+=-lrt -lpthread
# default case (host page size) # default case (host page size)
run-test-mmap: test-mmap run-test-mmap: test-mmap
$(call run-test, test-mmap, $(QEMU) $<, \ $(call run-test, test-mmap, $(QEMU) $<, $< (default))
"$< (default) on $(TARGET_NAME)")
# additional page sizes (defined by each architecture adding to EXTRA_RUNS) # additional page sizes (defined by each architecture adding to EXTRA_RUNS)
run-test-mmap-%: test-mmap run-test-mmap-%: test-mmap
$(call run-test, test-mmap-$*, $(QEMU) -p $* $<,\ $(call run-test, test-mmap-$*, $(QEMU) -p $* $<, $< ($* byte pages))
"$< ($* byte pages) on $(TARGET_NAME)")
ifneq ($(HAVE_GDB_BIN),) ifneq ($(HAVE_GDB_BIN),)
GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
@ -58,21 +56,21 @@ run-gdbstub-sha1: sha1
--gdb $(HAVE_GDB_BIN) \ --gdb $(HAVE_GDB_BIN) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(MULTIARCH_SRC)/gdbstub/sha1.py, \ --bin $< --test $(MULTIARCH_SRC)/gdbstub/sha1.py, \
"basic gdbstub support") basic gdbstub support)
run-gdbstub-qxfer-auxv-read: sha1 run-gdbstub-qxfer-auxv-read: sha1
$(call run-test, $@, $(GDB_SCRIPT) \ $(call run-test, $@, $(GDB_SCRIPT) \
--gdb $(HAVE_GDB_BIN) \ --gdb $(HAVE_GDB_BIN) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(MULTIARCH_SRC)/gdbstub/test-qxfer-auxv-read.py, \ --bin $< --test $(MULTIARCH_SRC)/gdbstub/test-qxfer-auxv-read.py, \
"basic gdbstub qXfer:auxv:read support") basic gdbstub qXfer:auxv:read support)
run-gdbstub-thread-breakpoint: testthread run-gdbstub-thread-breakpoint: testthread
$(call run-test, $@, $(GDB_SCRIPT) \ $(call run-test, $@, $(GDB_SCRIPT) \
--gdb $(HAVE_GDB_BIN) \ --gdb $(HAVE_GDB_BIN) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(MULTIARCH_SRC)/gdbstub/test-thread-breakpoint.py, \ --bin $< --test $(MULTIARCH_SRC)/gdbstub/test-thread-breakpoint.py, \
"hitting a breakpoint on non-main thread") hitting a breakpoint on non-main thread)
else else
run-gdbstub-%: run-gdbstub-%:
@ -94,13 +92,13 @@ VPATH += $(MULTIARCH_SRC)/arm-compat-semi
semihosting: CFLAGS+=-I$(SRC_PATH)/tests/tcg/$(TARGET_NAME) semihosting: CFLAGS+=-I$(SRC_PATH)/tests/tcg/$(TARGET_NAME)
run-semihosting: semihosting run-semihosting: semihosting
$(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)") $(call run-test,$<,$(QEMU) $< 2> $<.err)
run-plugin-semihosting-with-%: run-plugin-semihosting-with-%:
$(call run-test, $@, $(QEMU) $(QEMU_OPTS) \ $(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
-plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \ -plugin $(PLUGIN_LIB)/$(call extract-plugin,$@) \
$(call strip-plugin,$<) 2> $<.err, \ $(call strip-plugin,$<) 2> $<.err, \
"$< on $(TARGET_NAME) with $*") $< with $*)
semiconsole: CFLAGS+=-I$(SRC_PATH)/tests/tcg/$(TARGET_NAME) semiconsole: CFLAGS+=-I$(SRC_PATH)/tests/tcg/$(TARGET_NAME)

View File

@ -25,7 +25,7 @@ run-gdbstub-memory: memory
--qargs \ --qargs \
"-monitor none -display none -chardev file$(COMMA)path=$<.out$(COMMA)id=output $(QEMU_OPTS)" \ "-monitor none -display none -chardev file$(COMMA)path=$<.out$(COMMA)id=output $(QEMU_OPTS)" \
--bin $< --test $(MULTIARCH_SRC)/gdbstub/memory.py, \ --bin $< --test $(MULTIARCH_SRC)/gdbstub/memory.py, \
"softmmu gdbstub support") softmmu gdbstub support)
else else
run-gdbstub-%: run-gdbstub-%:

View File

@ -3,7 +3,13 @@
# ppc64 specific tweaks # ppc64 specific tweaks
VPATH += $(SRC_PATH)/tests/tcg/ppc64 VPATH += $(SRC_PATH)/tests/tcg/ppc64
VPATH += $(SRC_PATH)/tests/tcg/ppc64le
config-cc.mak: Makefile
$(quiet-@)( \
$(call cc-option,-mpower8-vector, CROSS_CC_HAS_POWER8_VECTOR); \
$(call cc-option,-mpower10, CROSS_CC_HAS_POWER10)) 3> config-cc.mak
-include config-cc.mak
ifneq ($(CROSS_CC_HAS_POWER8_VECTOR),) ifneq ($(CROSS_CC_HAS_POWER8_VECTOR),)
PPC64_TESTS=bcdsub non_signalling_xscv PPC64_TESTS=bcdsub non_signalling_xscv

View File

@ -4,28 +4,4 @@
VPATH += $(SRC_PATH)/tests/tcg/ppc64le VPATH += $(SRC_PATH)/tests/tcg/ppc64le
ifneq ($(CROSS_CC_HAS_POWER8_VECTOR),) include $(SRC_PATH)/tests/tcg/ppc64/Makefile.target
PPC64LE_TESTS=bcdsub non_signalling_xscv
endif
$(PPC64LE_TESTS): CFLAGS += -mpower8-vector
ifneq ($(CROSS_CC_HAS_POWER10),)
PPC64LE_TESTS += byte_reverse sha512-vector
endif
byte_reverse: CFLAGS += -mcpu=power10
run-byte_reverse: QEMU_OPTS+=-cpu POWER10
run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10
sha512-vector: CFLAGS +=-mcpu=power10 -O3
sha512-vector: sha512.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
run-sha512-vector: QEMU_OPTS+=-cpu POWER10
run-plugin-sha512-vector-with-%: QEMU_OPTS+=-cpu POWER10
PPC64LE_TESTS += mtfsf
PPC64LE_TESTS += mffsce
PPC64LE_TESTS += signal_save_restore_xer
PPC64LE_TESTS += xxspltw
TESTS += $(PPC64LE_TESTS)

View File

@ -41,7 +41,7 @@ run-gdbstub-signals-s390x: signals-s390x
--gdb $(HAVE_GDB_BIN) \ --gdb $(HAVE_GDB_BIN) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(S390X_SRC)/gdbstub/test-signals-s390x.py, \ --bin $< --test $(S390X_SRC)/gdbstub/test-signals-s390x.py, \
"mixing signals and debugging on s390x") mixing signals and debugging)
EXTRA_RUNS += run-gdbstub-signals-s390x EXTRA_RUNS += run-gdbstub-signals-s390x
endif endif

View File

@ -40,8 +40,7 @@ run-plugin-%-with-libinsn.so:
-chardev file$(COMMA)path=$@.out$(COMMA)id=output \ -chardev file$(COMMA)path=$@.out$(COMMA)id=output \
-plugin ../../plugin/libinsn.so$(COMMA)inline=on \ -plugin ../../plugin/libinsn.so$(COMMA)inline=on \
-d plugin -D $*-with-libinsn.so.pout \ -d plugin -D $*-with-libinsn.so.pout \
$(QEMU_OPTS) $*, \ $(QEMU_OPTS) $*)
"$* on $(TARGET_NAME)")
# Running # Running
QEMU_OPTS+=-device isa-debugcon,chardev=output -device isa-debug-exit,iobase=0xf4,iosize=0x4 -kernel QEMU_OPTS+=-device isa-debugcon,chardev=output -device isa-debug-exit,iobase=0xf4,iosize=0x4 -kernel

View File

@ -46,34 +46,6 @@ ram_block_discard_range(const char *rbname, void *hva, size_t length, bool need_
memory_notdirty_write_access(uint64_t vaddr, uint64_t ram_addr, unsigned size) "0x%" PRIx64 " ram_addr 0x%" PRIx64 " size %u" memory_notdirty_write_access(uint64_t vaddr, uint64_t ram_addr, unsigned size) "0x%" PRIx64 " ram_addr 0x%" PRIx64 " size %u"
memory_notdirty_set_dirty(uint64_t vaddr) "0x%" PRIx64 memory_notdirty_set_dirty(uint64_t vaddr) "0x%" PRIx64
# gdbstub.c
gdbstub_op_start(const char *device) "Starting gdbstub using device %s"
gdbstub_op_exiting(uint8_t code) "notifying exit with code=0x%02x"
gdbstub_op_continue(void) "Continuing all CPUs"
gdbstub_op_continue_cpu(int cpu_index) "Continuing CPU %d"
gdbstub_op_stepping(int cpu_index) "Stepping CPU %d"
gdbstub_op_extra_info(const char *info) "Thread extra info: %s"
gdbstub_hit_watchpoint(const char *type, int cpu_gdb_index, uint64_t vaddr) "Watchpoint hit, type=\"%s\" cpu=%d, vaddr=0x%" PRIx64 ""
gdbstub_hit_internal_error(void) "RUN_STATE_INTERNAL_ERROR"
gdbstub_hit_break(void) "RUN_STATE_DEBUG"
gdbstub_hit_paused(void) "RUN_STATE_PAUSED"
gdbstub_hit_shutdown(void) "RUN_STATE_SHUTDOWN"
gdbstub_hit_io_error(void) "RUN_STATE_IO_ERROR"
gdbstub_hit_watchdog(void) "RUN_STATE_WATCHDOG"
gdbstub_hit_unknown(int state) "Unknown run state=0x%x"
gdbstub_io_reply(const char *message) "Sent: %s"
gdbstub_io_binaryreply(size_t ofs, const char *line) "0x%04zx: %s"
gdbstub_io_command(const char *command) "Received: %s"
gdbstub_io_got_ack(void) "Got ACK"
gdbstub_io_got_unexpected(uint8_t ch) "Got 0x%02x when expecting ACK/NACK"
gdbstub_err_got_nack(void) "Got NACK, retransmitting"
gdbstub_err_garbage(uint8_t ch) "received garbage between packets: 0x%02x"
gdbstub_err_overrun(void) "command buffer overrun, dropping command"
gdbstub_err_invalid_repeat(uint8_t ch) "got invalid RLE count: 0x%02x"
gdbstub_err_invalid_rle(void) "got invalid RLE sequence"
gdbstub_err_checksum_invalid(uint8_t ch) "got invalid command checksum digit: 0x%02x"
gdbstub_err_checksum_incorrect(uint8_t expected, uint8_t got) "got command packet with incorrect checksum, expected=0x%02x, received=0x%02x"
# job.c # job.c
job_state_transition(void *job, int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)" job_state_transition(void *job, int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
job_apply_verb(void *job, const char *state, const char *verb, const char *legal) "job %p in state %s; applying verb %s (%s)" job_apply_verb(void *job, const char *state, const char *verb, const char *legal) "job %p in state %s; applying verb %s (%s)"