testing, gdbstub and plugin updates

- enable more sbsa-ref tests in avocado
   - add swtpm to the package lists
   - reduce avocado noise in gitlab by limiting tests
   - make docker engine choice driven by configure and enable override
   - remove unneeded gcc suffix on some cross compilers
   - fix some NULL returns in gdbstub
   - improve locking in execlog plugin
   - introduce the GDBFeature structure
   - consistently set gdb_core_xml_file
   - use cleaner escaping for gdb xml
   - drop ancient gdb_has_xml() test
   - disable multi-instruction GUSA emulation when plugins enabled
   - fix some coverity issues in plugins
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmUmVJkACgkQ+9DbCVqe
 KkTfNggAiS02FcL3faGjAN9+60xhvEQ3DJjI473hjvFWu0bSkQTjObcQqGc+V7Cw
 9yNtnxOOWB6KdAU8At7HlVqiUXeyTCJB7Att5/UgNUZj63j+cs7PXb4p7cVCcJOc
 17zni22tnmCBcC8wZaz0yj68jaftL3hz1QNUZOmv6CBt42q0+/4g1WKfaJ+w+SbK
 T7cJEiMDObm8qeNAAXpDLB+9v3bRDxMZ8hFJ3p3CatQC8jbDrkuH7RrVPHDWiWQx
 w0uXpUHlZEOVX23v6+iIoeb8YQW2bZI9UsfeyIHJlENaVgyL200LHgLvvAE4Qd63
 dCtfQUZzj4t9sfoL4XgxaB7G4qtXTg==
 =7PLI
 -----END PGP SIGNATURE-----

Merge tag 'pull-omnibus-111023-1' of https://gitlab.com/stsquad/qemu into staging

testing, gdbstub and plugin updates

  - enable more sbsa-ref tests in avocado
  - add swtpm to the package lists
  - reduce avocado noise in gitlab by limiting tests
  - make docker engine choice driven by configure and enable override
  - remove unneeded gcc suffix on some cross compilers
  - fix some NULL returns in gdbstub
  - improve locking in execlog plugin
  - introduce the GDBFeature structure
  - consistently set gdb_core_xml_file
  - use cleaner escaping for gdb xml
  - drop ancient gdb_has_xml() test
  - disable multi-instruction GUSA emulation when plugins enabled
  - fix some coverity issues in plugins

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmUmVJkACgkQ+9DbCVqe
# KkTfNggAiS02FcL3faGjAN9+60xhvEQ3DJjI473hjvFWu0bSkQTjObcQqGc+V7Cw
# 9yNtnxOOWB6KdAU8At7HlVqiUXeyTCJB7Att5/UgNUZj63j+cs7PXb4p7cVCcJOc
# 17zni22tnmCBcC8wZaz0yj68jaftL3hz1QNUZOmv6CBt42q0+/4g1WKfaJ+w+SbK
# T7cJEiMDObm8qeNAAXpDLB+9v3bRDxMZ8hFJ3p3CatQC8jbDrkuH7RrVPHDWiWQx
# w0uXpUHlZEOVX23v6+iIoeb8YQW2bZI9UsfeyIHJlENaVgyL200LHgLvvAE4Qd63
# dCtfQUZzj4t9sfoL4XgxaB7G4qtXTg==
# =7PLI
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 11 Oct 2023 03:54:01 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-omnibus-111023-1' of https://gitlab.com/stsquad/qemu: (25 commits)
  contrib/plugins: fix coverity warning in hotblocks
  contrib/plugins: fix coverity warning in lockstep
  contrib/plugins: fix coverity warning in cache
  plugins: Set final instruction count in plugin_gen_tb_end
  target/sh4: Disable decode_gusa when plugins enabled
  accel/tcg: Add plugin_enabled to DisasContextBase
  gdbstub: Replace gdb_regs with an array
  gdbstub: Remove gdb_has_xml variable
  target/ppc: Remove references to gdb_has_xml
  target/arm: Remove references to gdb_has_xml
  gdbstub: Use g_markup_printf_escaped()
  hw/core/cpu: Return static value with gdb_arch_name()
  target/arm: Move the reference to arm-core.xml
  gdbstub: Introduce GDBFeature structure
  contrib/plugins: Use GRWLock in execlog
  plugins: Check if vCPU is realized
  gdbstub: Fix target.xml response
  gdbstub: Fix target_xml initialization
  configure: remove gcc version suffixes
  configure: allow user to override docker engine
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2023-10-11 09:43:10 -04:00
commit a51e5124a6
50 changed files with 304 additions and 273 deletions

View file

@ -30,6 +30,7 @@ avocado-system-alpine:
variables: variables:
IMAGE: alpine IMAGE: alpine
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado
AVOCADO_TAGS: arch:avr arch:loongarch64 arch:mips64 arch:mipsel
build-system-ubuntu: build-system-ubuntu:
extends: extends:
@ -40,8 +41,7 @@ build-system-ubuntu:
variables: variables:
IMAGE: ubuntu2204 IMAGE: ubuntu2204
CONFIGURE_ARGS: --enable-docs CONFIGURE_ARGS: --enable-docs
TARGETS: alpha-softmmu cris-softmmu hppa-softmmu TARGETS: alpha-softmmu microblazeel-softmmu mips64el-softmmu
microblazeel-softmmu mips64el-softmmu
MAKE_CHECK_ARGS: check-build MAKE_CHECK_ARGS: check-build
check-system-ubuntu: check-system-ubuntu:
@ -61,6 +61,7 @@ avocado-system-ubuntu:
variables: variables:
IMAGE: ubuntu2204 IMAGE: ubuntu2204
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado
AVOCADO_TAGS: arch:alpha arch:microblaze arch:mips64el
build-system-debian: build-system-debian:
extends: extends:
@ -72,7 +73,7 @@ build-system-debian:
IMAGE: debian-amd64 IMAGE: debian-amd64
CONFIGURE_ARGS: --with-coroutine=sigaltstack CONFIGURE_ARGS: --with-coroutine=sigaltstack
TARGETS: arm-softmmu i386-softmmu riscv64-softmmu sh4eb-softmmu TARGETS: arm-softmmu i386-softmmu riscv64-softmmu sh4eb-softmmu
sparc-softmmu xtensaeb-softmmu sparc-softmmu xtensa-softmmu
MAKE_CHECK_ARGS: check-build MAKE_CHECK_ARGS: check-build
check-system-debian: check-system-debian:
@ -92,6 +93,7 @@ avocado-system-debian:
variables: variables:
IMAGE: debian-amd64 IMAGE: debian-amd64
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado
AVOCADO_TAGS: arch:arm arch:i386 arch:riscv64 arch:sh4 arch:sparc arch:xtensa
crash-test-debian: crash-test-debian:
extends: .native_test_job_template extends: .native_test_job_template
@ -114,7 +116,7 @@ build-system-fedora:
variables: variables:
IMAGE: fedora IMAGE: fedora
CONFIGURE_ARGS: --disable-gcrypt --enable-nettle --enable-docs CONFIGURE_ARGS: --disable-gcrypt --enable-nettle --enable-docs
TARGETS: tricore-softmmu microblaze-softmmu mips-softmmu TARGETS: microblaze-softmmu mips-softmmu
xtensa-softmmu m68k-softmmu riscv32-softmmu ppc-softmmu sparc64-softmmu xtensa-softmmu m68k-softmmu riscv32-softmmu ppc-softmmu sparc64-softmmu
MAKE_CHECK_ARGS: check-build MAKE_CHECK_ARGS: check-build
@ -135,6 +137,8 @@ avocado-system-fedora:
variables: variables:
IMAGE: fedora IMAGE: fedora
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado
AVOCADO_TAGS: arch:microblaze arch:mips arch:xtensa arch:m68k
arch:riscv32 arch:ppc arch:sparc64
crash-test-fedora: crash-test-fedora:
extends: .native_test_job_template extends: .native_test_job_template
@ -180,6 +184,8 @@ avocado-system-centos:
variables: variables:
IMAGE: centos8 IMAGE: centos8
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado
AVOCADO_TAGS: arch:ppc64 arch:or1k arch:390x arch:x86_64 arch:rx
arch:sh4 arch:nios2
build-system-opensuse: build-system-opensuse:
extends: extends:
@ -209,6 +215,7 @@ avocado-system-opensuse:
variables: variables:
IMAGE: opensuse-leap IMAGE: opensuse-leap
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado
AVOCADO_TAGS: arch:s390x arch:x86_64 arch:aarch64
# This jobs explicitly disable TCG (--disable-tcg), KVM is detected by # This jobs explicitly disable TCG (--disable-tcg), KVM is detected by

View file

@ -11,6 +11,6 @@ MAKE='/opt/homebrew/bin/gmake'
NINJA='/opt/homebrew/bin/ninja' NINJA='/opt/homebrew/bin/ninja'
PACKAGING_COMMAND='brew' PACKAGING_COMMAND='brew'
PIP3='/opt/homebrew/bin/pip3' PIP3='/opt/homebrew/bin/pip3'
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 mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol tesseract usbredir vde vte3 xorriso 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 mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 xorriso zlib zstd'
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli' PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli'
PYTHON='/opt/homebrew/bin/python3' PYTHON='/opt/homebrew/bin/python3'

View file

@ -2842,7 +2842,7 @@ F: include/exec/gdbstub.h
F: include/gdbstub/* F: include/gdbstub/*
F: gdb-xml/ F: gdb-xml/
F: tests/tcg/multiarch/gdbstub/ F: tests/tcg/multiarch/gdbstub/
F: scripts/feature_to_c.sh F: scripts/feature_to_c.py
F: scripts/probe-gdb-support.py F: scripts/probe-gdb-support.py
Memory API Memory API

View file

@ -866,10 +866,14 @@ void plugin_gen_insn_end(void)
* do any clean-up here and make sure things are reset in * do any clean-up here and make sure things are reset in
* plugin_gen_tb_start. * plugin_gen_tb_start.
*/ */
void plugin_gen_tb_end(CPUState *cpu) void plugin_gen_tb_end(CPUState *cpu, size_t num_insns)
{ {
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb; struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
/* translator may have removed instructions, update final count */
g_assert(num_insns <= ptb->n);
ptb->n = num_insns;
/* collect instrumentation requests */ /* collect instrumentation requests */
qemu_plugin_tb_trans_cb(cpu, ptb); qemu_plugin_tb_trans_cb(cpu, ptb);

View file

@ -158,6 +158,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
} else { } else {
plugin_enabled = plugin_gen_tb_start(cpu, db, false); plugin_enabled = plugin_gen_tb_start(cpu, db, false);
} }
db->plugin_enabled = plugin_enabled;
while (true) { while (true) {
*max_insns = ++db->num_insns; *max_insns = ++db->num_insns;
@ -209,7 +210,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
gen_tb_end(tb, cflags, icount_start_insn, db->num_insns); gen_tb_end(tb, cflags, icount_start_insn, db->num_insns);
if (plugin_enabled) { if (plugin_enabled) {
plugin_gen_tb_end(cpu); plugin_gen_tb_end(cpu, db->num_insns);
} }
/* The disas_log hook may use these values rather than recompute. */ /* The disas_log hook may use these values rather than recompute. */

13
configure vendored
View file

@ -180,6 +180,7 @@ fi
# some defaults, based on the host environment # some defaults, based on the host environment
# default parameters # default parameters
container_engine="auto"
cpu="" cpu=""
cross_compile="no" cross_compile="no"
cross_prefix="" cross_prefix=""
@ -787,6 +788,8 @@ for opt do
;; ;;
--disable-containers) use_containers="no" --disable-containers) use_containers="no"
;; ;;
--container-engine=*) container_engine="$optarg"
;;
--gdb=*) gdb_bin="$optarg" --gdb=*) gdb_bin="$optarg"
;; ;;
# everything else has the same name in configure and meson # everything else has the same name in configure and meson
@ -921,6 +924,7 @@ Advanced options (experts only):
--enable-plugins --enable-plugins
enable plugins via shared library loading enable plugins via shared library loading
--disable-containers don't use containers for cross-building --disable-containers don't use containers for cross-building
--container-engine=TYPE which container engine to use [$container_engine]
--gdb=GDB-path gdb to use for gdbstub tests [$gdb_bin] --gdb=GDB-path gdb to use for gdbstub tests [$gdb_bin]
EOF EOF
meson_options_help meson_options_help
@ -1195,14 +1199,14 @@ fi
container="no" container="no"
runc="" runc=""
if test $use_containers = "yes" && (has "docker" || has "podman"); then if test $use_containers = "yes" && (has "docker" || has "podman"); then
case $($python "$source_path"/tests/docker/docker.py probe) in case $($python "$source_path"/tests/docker/docker.py --engine "$container_engine" probe) in
*docker) container=docker ;; *docker) container=docker ;;
podman) container=podman ;; podman) container=podman ;;
no) container=no ;; no) container=no ;;
esac esac
if test "$container" != "no"; then if test "$container" != "no"; then
docker_py="$python $source_path/tests/docker/docker.py --engine $container" docker_py="$python $source_path/tests/docker/docker.py --engine $container"
runc=$($python "$source_path"/tests/docker/docker.py probe) runc=$container
fi fi
fi fi
@ -1330,7 +1334,7 @@ probe_target_compiler() {
# We don't have any bigendian build tools so we only use this for AArch64 # We don't have any bigendian build tools so we only use this for AArch64
container_image=debian-arm64-cross container_image=debian-arm64-cross
container_cross_prefix=aarch64-linux-gnu- container_cross_prefix=aarch64-linux-gnu-
container_cross_cc=${container_cross_prefix}gcc-10 container_cross_cc=${container_cross_prefix}gcc
;; ;;
alpha) alpha)
container_image=debian-alpha-cross container_image=debian-alpha-cross
@ -1393,7 +1397,7 @@ probe_target_compiler() {
ppc) ppc)
container_image=debian-powerpc-test-cross container_image=debian-powerpc-test-cross
container_cross_prefix=powerpc-linux-gnu- container_cross_prefix=powerpc-linux-gnu-
container_cross_cc=${container_cross_prefix}gcc-10 container_cross_cc=${container_cross_prefix}gcc
;; ;;
ppc64|ppc64le) ppc64|ppc64le)
container_image=debian-powerpc-test-cross container_image=debian-powerpc-test-cross
@ -1694,7 +1698,6 @@ if test -n "$gdb_bin"; then
fi fi
if test "$container" != no; then if test "$container" != no; then
echo "ENGINE=$container" >> $config_host_mak
echo "RUNC=$runc" >> $config_host_mak echo "RUNC=$runc" >> $config_host_mak
fi fi
echo "SUBDIRS=$subdirs" >> $config_host_mak echo "SUBDIRS=$subdirs" >> $config_host_mak

View file

@ -535,15 +535,13 @@ static void caches_free(Cache **caches)
} }
} }
static void append_stats_line(GString *line, uint64_t l1_daccess, static void append_stats_line(GString *line,
uint64_t l1_dmisses, uint64_t l1_iaccess, uint64_t l1_daccess, uint64_t l1_dmisses,
uint64_t l1_imisses, uint64_t l2_access, uint64_t l1_iaccess, uint64_t l1_imisses,
uint64_t l2_misses) uint64_t l2_access, uint64_t l2_misses)
{ {
double l1_dmiss_rate, l1_imiss_rate, l2_miss_rate; double l1_dmiss_rate = ((double) l1_dmisses) / (l1_daccess) * 100.0;
double l1_imiss_rate = ((double) l1_imisses) / (l1_iaccess) * 100.0;
l1_dmiss_rate = ((double) l1_dmisses) / (l1_daccess) * 100.0;
l1_imiss_rate = ((double) l1_imisses) / (l1_iaccess) * 100.0;
g_string_append_printf(line, "%-14" PRIu64 " %-12" PRIu64 " %9.4lf%%" g_string_append_printf(line, "%-14" PRIu64 " %-12" PRIu64 " %9.4lf%%"
" %-14" PRIu64 " %-12" PRIu64 " %9.4lf%%", " %-14" PRIu64 " %-12" PRIu64 " %9.4lf%%",
@ -554,8 +552,8 @@ static void append_stats_line(GString *line, uint64_t l1_daccess,
l1_imisses, l1_imisses,
l1_iaccess ? l1_imiss_rate : 0.0); l1_iaccess ? l1_imiss_rate : 0.0);
if (use_l2) { if (l2_access && l2_misses) {
l2_miss_rate = ((double) l2_misses) / (l2_access) * 100.0; double l2_miss_rate = ((double) l2_misses) / (l2_access) * 100.0;
g_string_append_printf(line, g_string_append_printf(line,
" %-12" PRIu64 " %-11" PRIu64 " %10.4lf%%", " %-12" PRIu64 " %-11" PRIu64 " %10.4lf%%",
l2_access, l2_access,

View file

@ -19,7 +19,7 @@ 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 */
static GPtrArray *last_exec; static GPtrArray *last_exec;
static GMutex expand_array_lock; static GRWLock expand_array_lock;
static GPtrArray *imatches; static GPtrArray *imatches;
static GArray *amatches; static GArray *amatches;
@ -28,18 +28,16 @@ static GArray *amatches;
* Expand last_exec array. * Expand last_exec array.
* *
* As we could have multiple threads trying to do this we need to * As we could have multiple threads trying to do this we need to
* serialise the expansion under a lock. Threads accessing already * serialise the expansion under a lock.
* created entries can continue without issue even if the ptr array
* gets reallocated during resize.
*/ */
static void expand_last_exec(int cpu_index) static void expand_last_exec(int cpu_index)
{ {
g_mutex_lock(&expand_array_lock); g_rw_lock_writer_lock(&expand_array_lock);
while (cpu_index >= last_exec->len) { while (cpu_index >= last_exec->len) {
GString *s = g_string_new(NULL); GString *s = g_string_new(NULL);
g_ptr_array_add(last_exec, s); g_ptr_array_add(last_exec, s);
} }
g_mutex_unlock(&expand_array_lock); g_rw_lock_writer_unlock(&expand_array_lock);
} }
/** /**
@ -51,8 +49,10 @@ static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t info,
GString *s; GString *s;
/* Find vCPU in array */ /* Find vCPU in array */
g_rw_lock_reader_lock(&expand_array_lock);
g_assert(cpu_index < last_exec->len); g_assert(cpu_index < last_exec->len);
s = g_ptr_array_index(last_exec, cpu_index); s = g_ptr_array_index(last_exec, cpu_index);
g_rw_lock_reader_unlock(&expand_array_lock);
/* Indicate type of memory access */ /* Indicate type of memory access */
if (qemu_plugin_mem_is_store(info)) { if (qemu_plugin_mem_is_store(info)) {
@ -80,10 +80,14 @@ static void vcpu_insn_exec(unsigned int cpu_index, void *udata)
GString *s; GString *s;
/* Find or create vCPU in array */ /* Find or create vCPU in array */
g_rw_lock_reader_lock(&expand_array_lock);
if (cpu_index >= last_exec->len) { if (cpu_index >= last_exec->len) {
g_rw_lock_reader_unlock(&expand_array_lock);
expand_last_exec(cpu_index); expand_last_exec(cpu_index);
g_rw_lock_reader_lock(&expand_array_lock);
} }
s = g_ptr_array_index(last_exec, cpu_index); s = g_ptr_array_index(last_exec, cpu_index);
g_rw_lock_reader_unlock(&expand_array_lock);
/* Print previous instruction in cache */ /* Print previous instruction in cache */
if (s->len) { if (s->len) {

View file

@ -69,8 +69,8 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
} }
g_list_free(it); g_list_free(it);
g_mutex_unlock(&lock);
} }
g_mutex_unlock(&lock);
qemu_plugin_outs(report->str); qemu_plugin_outs(report->str);
} }

View file

@ -245,6 +245,7 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
static bool setup_socket(const char *path) static bool setup_socket(const char *path)
{ {
struct sockaddr_un sockaddr; struct sockaddr_un sockaddr;
const gsize pathlen = sizeof(sockaddr.sun_path) - 1;
int fd; int fd;
fd = socket(AF_UNIX, SOCK_STREAM, 0); fd = socket(AF_UNIX, SOCK_STREAM, 0);
@ -254,7 +255,11 @@ static bool setup_socket(const char *path)
} }
sockaddr.sun_family = AF_UNIX; sockaddr.sun_family = AF_UNIX;
g_strlcpy(sockaddr.sun_path, path, sizeof(sockaddr.sun_path) - 1); if (g_strlcpy(sockaddr.sun_path, path, pathlen) >= pathlen) {
perror("bad path");
return false;
}
if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) { if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) {
perror("bind socket"); perror("bind socket");
close(fd); close(fd);
@ -287,6 +292,7 @@ static bool connect_socket(const char *path)
{ {
int fd; int fd;
struct sockaddr_un sockaddr; struct sockaddr_un sockaddr;
const gsize pathlen = sizeof(sockaddr.sun_path) - 1;
fd = socket(AF_UNIX, SOCK_STREAM, 0); fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) { if (fd < 0) {
@ -295,7 +301,10 @@ static bool connect_socket(const char *path)
} }
sockaddr.sun_family = AF_UNIX; sockaddr.sun_family = AF_UNIX;
g_strlcpy(sockaddr.sun_path, path, sizeof(sockaddr.sun_path) - 1); if (g_strlcpy(sockaddr.sun_path, path, pathlen) >= pathlen) {
perror("bad path");
return false;
}
if (connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) { if (connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) {
perror("failed to connect"); perror("failed to connect");

View file

@ -51,7 +51,6 @@ typedef struct GDBRegisterState {
gdb_get_reg_cb get_reg; gdb_get_reg_cb get_reg;
gdb_set_reg_cb set_reg; gdb_set_reg_cb set_reg;
const char *xml; const char *xml;
struct GDBRegisterState *next;
} GDBRegisterState; } GDBRegisterState;
GDBState gdbserver_state; GDBState gdbserver_state;
@ -349,11 +348,6 @@ static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
} }
} }
bool gdb_has_xml(void)
{
return !!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml;
}
static const char *get_feature_xml(const char *p, const char **newp, static const char *get_feature_xml(const char *p, const char **newp,
GDBProcess *process) GDBProcess *process)
{ {
@ -373,31 +367,37 @@ static const char *get_feature_xml(const char *p, const char **newp,
if (strncmp(p, "target.xml", len) == 0) { if (strncmp(p, "target.xml", len) == 0) {
if (!process->target_xml) { if (!process->target_xml) {
GDBRegisterState *r; GDBRegisterState *r;
GString *xml = g_string_new("<?xml version=\"1.0\"?>"); g_autoptr(GPtrArray) xml = g_ptr_array_new_with_free_func(g_free);
g_string_append(xml, g_ptr_array_add(
xml,
g_strdup("<?xml version=\"1.0\"?>"
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">" "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target>"); "<target>"));
if (cc->gdb_arch_name) { if (cc->gdb_arch_name) {
g_autofree gchar *arch = cc->gdb_arch_name(cpu); g_ptr_array_add(
g_string_append_printf(xml, xml,
"<architecture>%s</architecture>", g_markup_printf_escaped("<architecture>%s</architecture>",
arch); cc->gdb_arch_name(cpu)));
} }
g_string_append(xml, "<xi:include href=\""); g_ptr_array_add(
g_string_append(xml, cc->gdb_core_xml_file); xml,
g_string_append(xml, "\"/>"); g_markup_printf_escaped("<xi:include href=\"%s\"/>",
for (r = cpu->gdb_regs; r; r = r->next) { cc->gdb_core_xml_file));
g_string_append(xml, "<xi:include href=\""); for (guint i = 0; i < cpu->gdb_regs->len; i++) {
g_string_append(xml, r->xml); r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
g_string_append(xml, "\"/>"); g_ptr_array_add(
xml,
g_markup_printf_escaped("<xi:include href=\"%s\"/>",
r->xml));
} }
g_string_append(xml, "</target>"); g_ptr_array_add(xml, g_strdup("</target>"));
g_ptr_array_add(xml, NULL);
process->target_xml = g_string_free(xml, false); process->target_xml = g_strjoinv(NULL, (void *)xml->pdata);
return process->target_xml;
} }
return process->target_xml;
} }
/* Is it dynamically generated by the target? */ /* Is it dynamically generated by the target? */
if (cc->gdb_get_dynamic_xml) { if (cc->gdb_get_dynamic_xml) {
@ -408,11 +408,11 @@ static const char *get_feature_xml(const char *p, const char **newp,
} }
} }
/* Is it one of the encoded gdb-xml/ files? */ /* Is it one of the encoded gdb-xml/ files? */
for (int i = 0; xml_builtin[i][0]; i++) { for (int i = 0; gdb_static_features[i].xmlname; i++) {
const char *name = xml_builtin[i][0]; const char *name = gdb_static_features[i].xmlname;
if ((strncmp(name, p, len) == 0) && if ((strncmp(name, p, len) == 0) &&
strlen(name) == len) { strlen(name) == len) {
return xml_builtin[i][1]; return gdb_static_features[i].xml;
} }
} }
@ -430,7 +430,8 @@ static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
return cc->gdb_read_register(cpu, buf, reg); return cc->gdb_read_register(cpu, buf, reg);
} }
for (r = cpu->gdb_regs; r; r = r->next) { for (guint i = 0; i < cpu->gdb_regs->len; i++) {
r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
return r->get_reg(env, buf, reg - r->base_reg); return r->get_reg(env, buf, reg - r->base_reg);
} }
@ -448,7 +449,8 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
return cc->gdb_write_register(cpu, mem_buf, reg); return cc->gdb_write_register(cpu, mem_buf, reg);
} }
for (r = cpu->gdb_regs; r; r = r->next) { for (guint i = 0; i < cpu->gdb_regs->len; i++) {
r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
return r->set_reg(env, mem_buf, reg - r->base_reg); return r->set_reg(env, mem_buf, reg - r->base_reg);
} }
@ -461,17 +463,23 @@ void gdb_register_coprocessor(CPUState *cpu,
int num_regs, const char *xml, int g_pos) int num_regs, const char *xml, int g_pos)
{ {
GDBRegisterState *s; GDBRegisterState *s;
GDBRegisterState **p; guint i;
p = &cpu->gdb_regs; if (cpu->gdb_regs) {
while (*p) { for (i = 0; i < cpu->gdb_regs->len; i++) {
/* Check for duplicates. */ /* Check for duplicates. */
if (strcmp((*p)->xml, xml) == 0) s = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
if (strcmp(s->xml, xml) == 0) {
return; return;
p = &(*p)->next; }
}
} else {
cpu->gdb_regs = g_array_new(false, false, sizeof(GDBRegisterState));
i = 0;
} }
s = g_new0(GDBRegisterState, 1); g_array_set_size(cpu->gdb_regs, i + 1);
s = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
s->base_reg = cpu->gdb_num_regs; s->base_reg = cpu->gdb_num_regs;
s->num_regs = num_regs; s->num_regs = num_regs;
s->get_reg = get_reg; s->get_reg = get_reg;
@ -480,7 +488,6 @@ void gdb_register_coprocessor(CPUState *cpu,
/* Add to end of list. */ /* Add to end of list. */
cpu->gdb_num_regs += num_regs; cpu->gdb_num_regs += num_regs;
*p = s;
if (g_pos) { if (g_pos) {
if (g_pos != s->base_reg) { if (g_pos != s->base_reg) {
error_report("Error: Bad gdb register numbering for '%s', " error_report("Error: Bad gdb register numbering for '%s', "
@ -1081,11 +1088,6 @@ static void handle_set_reg(GArray *params, void *user_ctx)
{ {
int reg_size; int reg_size;
if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) {
gdb_put_packet("");
return;
}
if (params->len != 2) { if (params->len != 2) {
gdb_put_packet("E22"); gdb_put_packet("E22");
return; return;
@ -1102,11 +1104,6 @@ static void handle_get_reg(GArray *params, void *user_ctx)
{ {
int reg_size; int reg_size;
if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) {
gdb_put_packet("");
return;
}
if (!params->len) { if (!params->len) {
gdb_put_packet("E14"); gdb_put_packet("E14");
return; return;

View file

@ -32,8 +32,6 @@ enum {
typedef struct GDBProcess { typedef struct GDBProcess {
uint32_t pid; uint32_t pid;
bool attached; bool attached;
/* If gdb sends qXfer:features:read:target.xml this will be populated */
char *target_xml; char *target_xml;
} GDBProcess; } GDBProcess;

View file

@ -292,7 +292,7 @@ static int find_cpu_clusters(Object *child, void *opaque)
assert(cluster->cluster_id != UINT32_MAX); assert(cluster->cluster_id != UINT32_MAX);
process->pid = cluster->cluster_id + 1; process->pid = cluster->cluster_id + 1;
process->attached = false; process->attached = false;
process->target_xml[0] = '\0'; process->target_xml = NULL;
return 0; return 0;
} }

View file

@ -10,6 +10,11 @@
#define GDB_WATCHPOINT_READ 3 #define GDB_WATCHPOINT_READ 3
#define GDB_WATCHPOINT_ACCESS 4 #define GDB_WATCHPOINT_ACCESS 4
typedef struct GDBFeature {
const char *xmlname;
const char *xml;
} GDBFeature;
/* Get or set a register. Returns the size of the register. */ /* Get or set a register. Returns the size of the register. */
typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg); typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg);
@ -40,15 +45,7 @@ int gdbserver_start(const char *port_or_device);
void gdb_set_stop_cpu(CPUState *cpu); void gdb_set_stop_cpu(CPUState *cpu);
/** /* in gdbstub-xml.c, generated by scripts/feature_to_c.py */
* gdb_has_xml() - report of gdb supports modern target descriptions extern const GDBFeature gdb_static_features[];
*
* This will report true if the gdb negotiated qXfer:features:read
* target descriptions.
*/
bool gdb_has_xml(void);
/* in gdbstub-xml.c, generated by scripts/feature_to_c.sh */
extern const char *const xml_builtin[][2];
#endif #endif

View file

@ -20,7 +20,7 @@ struct DisasContextBase;
bool plugin_gen_tb_start(CPUState *cpu, const struct DisasContextBase *db, bool plugin_gen_tb_start(CPUState *cpu, const struct DisasContextBase *db,
bool supress); bool supress);
void plugin_gen_tb_end(CPUState *cpu); void plugin_gen_tb_end(CPUState *cpu, size_t num_insns);
void plugin_gen_insn_start(CPUState *cpu, const struct DisasContextBase *db); void plugin_gen_insn_start(CPUState *cpu, const struct DisasContextBase *db);
void plugin_gen_insn_end(void); void plugin_gen_insn_end(void);
@ -42,7 +42,7 @@ void plugin_gen_insn_start(CPUState *cpu, const struct DisasContextBase *db)
static inline void plugin_gen_insn_end(void) static inline void plugin_gen_insn_end(void)
{ } { }
static inline void plugin_gen_tb_end(CPUState *cpu) static inline void plugin_gen_tb_end(CPUState *cpu, size_t num_insns)
{ } { }
static inline void plugin_gen_disable_mem_helpers(void) static inline void plugin_gen_disable_mem_helpers(void)

View file

@ -73,6 +73,7 @@ typedef enum DisasJumpType {
* @max_insns: Maximum number of instructions to be translated in this TB. * @max_insns: Maximum number of instructions to be translated in this TB.
* @singlestep_enabled: "Hardware" single stepping enabled. * @singlestep_enabled: "Hardware" single stepping enabled.
* @saved_can_do_io: Known value of cpu->neg.can_do_io, or -1 for unknown. * @saved_can_do_io: Known value of cpu->neg.can_do_io, or -1 for unknown.
* @plugin_enabled: TCG plugin enabled in this TB.
* *
* Architecture-agnostic disassembly context. * Architecture-agnostic disassembly context.
*/ */
@ -85,6 +86,7 @@ typedef struct DisasContextBase {
int max_insns; int max_insns;
bool singlestep_enabled; bool singlestep_enabled;
int8_t saved_can_do_io; int8_t saved_can_do_io;
bool plugin_enabled;
void *host_addr[2]; void *host_addr[2];
} DisasContextBase; } DisasContextBase;

View file

@ -165,7 +165,7 @@ struct CPUClass {
vaddr (*gdb_adjust_breakpoint)(CPUState *cpu, vaddr addr); vaddr (*gdb_adjust_breakpoint)(CPUState *cpu, vaddr addr);
const char *gdb_core_xml_file; const char *gdb_core_xml_file;
gchar * (*gdb_arch_name)(CPUState *cpu); const gchar * (*gdb_arch_name)(CPUState *cpu);
const char * (*gdb_get_dynamic_xml)(CPUState *cpu, const char *xmlname); const char * (*gdb_get_dynamic_xml)(CPUState *cpu, const char *xmlname);
void (*disas_set_info)(CPUState *cpu, disassemble_info *info); void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
@ -502,7 +502,7 @@ struct CPUState {
CPUJumpCache *tb_jmp_cache; CPUJumpCache *tb_jmp_cache;
struct GDBRegisterState *gdb_regs; GArray *gdb_regs;
int gdb_num_regs; int gdb_num_regs;
int gdb_num_g_regs; int gdb_num_g_regs;
QTAILQ_ENTRY(CPUState) node; QTAILQ_ENTRY(CPUState) node;

View file

@ -3693,7 +3693,7 @@ common_all = static_library('common',
dependencies: common_all.dependencies(), dependencies: common_all.dependencies(),
name_suffix: 'fa') name_suffix: 'fa')
feature_to_c = find_program('scripts/feature_to_c.sh') feature_to_c = find_program('scripts/feature_to_c.py')
if targetos == 'darwin' if targetos == 'darwin'
entitlement = find_program('scripts/entitlement.sh') entitlement = find_program('scripts/entitlement.sh')

View file

@ -64,7 +64,7 @@ static void plugin_cpu_update__locked(gpointer k, gpointer v, gpointer udata)
CPUState *cpu = container_of(k, CPUState, cpu_index); CPUState *cpu = container_of(k, CPUState, cpu_index);
run_on_cpu_data mask = RUN_ON_CPU_HOST_ULONG(*plugin.mask); run_on_cpu_data mask = RUN_ON_CPU_HOST_ULONG(*plugin.mask);
if (cpu->created) { if (DEVICE(cpu)->realized) {
async_run_on_cpu(cpu, plugin_cpu_update__async, mask); async_run_on_cpu(cpu, plugin_cpu_update__async, mask);
} else { } else {
plugin_cpu_update__async(cpu, mask); plugin_cpu_update__async(cpu, mask);

48
scripts/feature_to_c.py Executable file
View file

@ -0,0 +1,48 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
import os, sys
def writeliteral(indent, bytes):
sys.stdout.write(' ' * indent)
sys.stdout.write('"')
quoted = True
for c in bytes:
if not quoted:
sys.stdout.write('\n')
sys.stdout.write(' ' * indent)
sys.stdout.write('"')
quoted = True
if c == b'"'[0]:
sys.stdout.write('\\"')
elif c == b'\\'[0]:
sys.stdout.write('\\\\')
elif c == b'\n'[0]:
sys.stdout.write('\\n"')
quoted = False
elif c >= 32 and c < 127:
sys.stdout.write(c.to_bytes(1, 'big').decode())
else:
sys.stdout.write(f'\{c:03o}')
if quoted:
sys.stdout.write('"')
sys.stdout.write('#include "qemu/osdep.h"\n' \
'#include "exec/gdbstub.h"\n' \
'\n'
'const GDBFeature gdb_static_features[] = {\n')
for input in sys.argv[1:]:
with open(input, 'rb') as file:
read = file.read()
sys.stdout.write(' {\n')
writeliteral(8, bytes(os.path.basename(input), 'utf-8'))
sys.stdout.write(',\n')
writeliteral(8, read)
sys.stdout.write('\n },\n')
sys.stdout.write(' { NULL }\n};\n')

View file

@ -1,69 +0,0 @@
#!/bin/sh
# Convert text files to compilable C arrays.
#
# Copyright (C) 2007 Free Software Foundation, Inc.
#
# This file is part of GDB.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
if test -z "$1"; then
echo "Usage: $0 INPUTFILE..."
exit 1
fi
for input; do
arrayname=xml_feature_$(echo $input | sed 's,.*/,,; s/[-.]/_/g')
${AWK:-awk} 'BEGIN { n = 0
printf "#include \"qemu/osdep.h\"\n"
print "static const char '$arrayname'[] = {"
for (i = 0; i < 255; i++)
_ord_[sprintf("%c", i)] = i
} {
split($0, line, "");
printf " "
for (i = 1; i <= length($0); i++) {
c = line[i]
if (c == "'\''") {
printf "'\''\\'\'''\'', "
} else if (c == "\\") {
printf "'\''\\\\'\'', "
} else if (_ord_[c] >= 32 && _ord_[c] < 127) {
printf "'\''%s'\'', ", c
} else {
printf "'\''\\%03o'\'', ", _ord_[c]
}
if (i % 10 == 0)
printf "\n "
}
printf "'\''\\n'\'', \n"
} END {
print " 0 };"
}' < $input
done
echo
echo '#include "exec/gdbstub.h"'
echo "const char *const xml_builtin[][2] = {"
for input; do
basename=$(echo $input | sed 's,.*/,,')
arrayname=xml_feature_$(echo $input | sed 's,.*/,,; s/[-.]/_/g')
echo " { \"$basename\", $arrayname },"
done
echo " { (char *)0, (char *)0 }"
echo "};"

View file

@ -1,6 +1,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "exec/gdbstub.h" /* xml_builtin */ #include "exec/gdbstub.h" /* gdb_static_features */
const char *const xml_builtin[][2] = { const GDBFeature gdb_static_features[] = {
{ NULL, NULL } { NULL }
}; };

View file

@ -2319,15 +2319,15 @@ static Property arm_cpu_properties[] = {
DEFINE_PROP_END_OF_LIST() DEFINE_PROP_END_OF_LIST()
}; };
static gchar *arm_gdb_arch_name(CPUState *cs) static const gchar *arm_gdb_arch_name(CPUState *cs)
{ {
ARMCPU *cpu = ARM_CPU(cs); ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env; CPUARMState *env = &cpu->env;
if (arm_feature(env, ARM_FEATURE_IWMMXT)) { if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
return g_strdup("iwmmxt"); return "iwmmxt";
} }
return g_strdup("arm"); return "arm";
} }
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
@ -2392,7 +2392,6 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->sysemu_ops = &arm_sysemu_ops; cc->sysemu_ops = &arm_sysemu_ops;
#endif #endif
cc->gdb_num_core_regs = 26; cc->gdb_num_core_regs = 26;
cc->gdb_core_xml_file = "arm-core.xml";
cc->gdb_arch_name = arm_gdb_arch_name; cc->gdb_arch_name = arm_gdb_arch_name;
cc->gdb_get_dynamic_xml = arm_gdb_get_dynamic_xml; cc->gdb_get_dynamic_xml = arm_gdb_get_dynamic_xml;
cc->gdb_stop_before_watchpoint = true; cc->gdb_stop_before_watchpoint = true;
@ -2414,8 +2413,10 @@ static void arm_cpu_instance_init(Object *obj)
static void cpu_register_class_init(ObjectClass *oc, void *data) static void cpu_register_class_init(ObjectClass *oc, void *data)
{ {
ARMCPUClass *acc = ARM_CPU_CLASS(oc); ARMCPUClass *acc = ARM_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(acc);
acc->info = data; acc->info = data;
cc->gdb_core_xml_file = "arm-core.xml";
} }
void arm_cpu_register(const ARMCPUInfo *info) void arm_cpu_register(const ARMCPUInfo *info)

View file

@ -781,9 +781,9 @@ static void aarch64_cpu_finalizefn(Object *obj)
{ {
} }
static gchar *aarch64_gdb_arch_name(CPUState *cs) static const gchar *aarch64_gdb_arch_name(CPUState *cs)
{ {
return g_strdup("aarch64"); return "aarch64";
} }
static void aarch64_cpu_class_init(ObjectClass *oc, void *data) static void aarch64_cpu_class_init(ObjectClass *oc, void *data)

View file

@ -46,21 +46,7 @@ int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
/* Core integer register. */ /* Core integer register. */
return gdb_get_reg32(mem_buf, env->regs[n]); return gdb_get_reg32(mem_buf, env->regs[n]);
} }
if (n < 24) { if (n == 25) {
/* FPA registers. */
if (gdb_has_xml()) {
return 0;
}
return gdb_get_zeroes(mem_buf, 12);
}
switch (n) {
case 24:
/* FPA status register. */
if (gdb_has_xml()) {
return 0;
}
return gdb_get_reg32(mem_buf, 0);
case 25:
/* CPSR, or XPSR for M-profile */ /* CPSR, or XPSR for M-profile */
if (arm_feature(env, ARM_FEATURE_M)) { if (arm_feature(env, ARM_FEATURE_M)) {
return gdb_get_reg32(mem_buf, xpsr_read(env)); return gdb_get_reg32(mem_buf, xpsr_read(env));
@ -100,21 +86,7 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
env->regs[n] = tmp; env->regs[n] = tmp;
return 4; return 4;
} }
if (n < 24) { /* 16-23 */ if (n == 25) {
/* FPA registers (ignored). */
if (gdb_has_xml()) {
return 0;
}
return 12;
}
switch (n) {
case 24:
/* FPA status register (ignored). */
if (gdb_has_xml()) {
return 0;
}
return 4;
case 25:
/* CPSR, or XPSR for M-profile */ /* CPSR, or XPSR for M-profile */
if (arm_feature(env, ARM_FEATURE_M)) { if (arm_feature(env, ARM_FEATURE_M)) {
/* /*

View file

@ -5916,12 +5916,12 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
memset(&env->user_features, 0, sizeof(env->user_features)); memset(&env->user_features, 0, sizeof(env->user_features));
} }
static gchar *x86_gdb_arch_name(CPUState *cs) static const gchar *x86_gdb_arch_name(CPUState *cs)
{ {
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
return g_strdup("i386:x86-64"); return "i386:x86-64";
#else #else
return g_strdup("i386"); return "i386";
#endif #endif
} }

View file

@ -766,9 +766,9 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
#endif #endif
} }
static gchar *loongarch32_gdb_arch_name(CPUState *cs) static const gchar *loongarch32_gdb_arch_name(CPUState *cs)
{ {
return g_strdup("loongarch32"); return "loongarch32";
} }
static void loongarch32_cpu_class_init(ObjectClass *c, void *data) static void loongarch32_cpu_class_init(ObjectClass *c, void *data)
@ -780,9 +780,9 @@ static void loongarch32_cpu_class_init(ObjectClass *c, void *data)
cc->gdb_arch_name = loongarch32_gdb_arch_name; cc->gdb_arch_name = loongarch32_gdb_arch_name;
} }
static gchar *loongarch64_gdb_arch_name(CPUState *cs) static const gchar *loongarch64_gdb_arch_name(CPUState *cs)
{ {
return g_strdup("loongarch64"); return "loongarch64";
} }
static void loongarch64_cpu_class_init(ObjectClass *c, void *data) static void loongarch64_cpu_class_init(ObjectClass *c, void *data)

View file

@ -54,12 +54,6 @@ static int ppc_gdb_register_len(int n)
case 0 ... 31: case 0 ... 31:
/* gprs */ /* gprs */
return sizeof(target_ulong); return sizeof(target_ulong);
case 32 ... 63:
/* fprs */
if (gdb_has_xml()) {
return 0;
}
return 8;
case 66: case 66:
/* cr */ /* cr */
case 69: case 69:
@ -74,12 +68,6 @@ static int ppc_gdb_register_len(int n)
case 68: case 68:
/* ctr */ /* ctr */
return sizeof(target_ulong); return sizeof(target_ulong);
case 70:
/* fpscr */
if (gdb_has_xml()) {
return 0;
}
return sizeof(target_ulong);
default: default:
return 0; return 0;
} }
@ -132,9 +120,6 @@ int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
if (n < 32) { if (n < 32) {
/* gprs */ /* gprs */
gdb_get_regl(buf, env->gpr[n]); gdb_get_regl(buf, env->gpr[n]);
} else if (n < 64) {
/* fprs */
gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
} else { } else {
switch (n) { switch (n) {
case 64: case 64:
@ -158,9 +143,6 @@ int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
case 69: case 69:
gdb_get_reg32(buf, cpu_read_xer(env)); gdb_get_reg32(buf, cpu_read_xer(env));
break; break;
case 70:
gdb_get_reg32(buf, env->fpscr);
break;
} }
} }
mem_buf = buf->data + buf->len - r; mem_buf = buf->data + buf->len - r;
@ -589,12 +571,12 @@ static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
return 0; return 0;
} }
gchar *ppc_gdb_arch_name(CPUState *cs) const gchar *ppc_gdb_arch_name(CPUState *cs)
{ {
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
return g_strdup("powerpc:common64"); return "powerpc:common64";
#else #else
return g_strdup("powerpc:common"); return "powerpc:common";
#endif #endif
} }

View file

@ -221,7 +221,7 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu);
/* gdbstub.c */ /* gdbstub.c */
void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc); void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
gchar *ppc_gdb_arch_name(CPUState *cs); const gchar *ppc_gdb_arch_name(CPUState *cs);
/** /**
* prot_for_access_type: * prot_for_access_type:

View file

@ -2004,17 +2004,17 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };
static gchar *riscv_gdb_arch_name(CPUState *cs) static const gchar *riscv_gdb_arch_name(CPUState *cs)
{ {
RISCVCPU *cpu = RISCV_CPU(cs); RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env; CPURISCVState *env = &cpu->env;
switch (riscv_cpu_mxl(env)) { switch (riscv_cpu_mxl(env)) {
case MXL_RV32: case MXL_RV32:
return g_strdup("riscv:rv32"); return "riscv:rv32";
case MXL_RV64: case MXL_RV64:
case MXL_RV128: case MXL_RV128:
return g_strdup("riscv:rv64"); return "riscv:rv64";
default: default:
g_assert_not_reached(); g_assert_not_reached();
} }

View file

@ -282,9 +282,9 @@ static void s390_cpu_initfn(Object *obj)
#endif #endif
} }
static gchar *s390_gdb_arch_name(CPUState *cs) static const gchar *s390_gdb_arch_name(CPUState *cs)
{ {
return g_strdup("s390:64-bit"); return "s390:64-bit";
} }
static Property s390x_cpu_properties[] = { static Property s390x_cpu_properties[] = {

View file

@ -1816,6 +1816,18 @@ static void decode_opc(DisasContext * ctx)
} }
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
/*
* Restart with the EXCLUSIVE bit set, within a TB run via
* cpu_exec_step_atomic holding the exclusive lock.
*/
static void gen_restart_exclusive(DisasContext *ctx)
{
ctx->envflags |= TB_FLAG_GUSA_EXCLUSIVE;
gen_save_cpu_state(ctx, false);
gen_helper_exclusive(tcg_env);
ctx->base.is_jmp = DISAS_NORETURN;
}
/* For uniprocessors, SH4 uses optimistic restartable atomic sequences. /* For uniprocessors, SH4 uses optimistic restartable atomic sequences.
Upon an interrupt, a real kernel would simply notice magic values in Upon an interrupt, a real kernel would simply notice magic values in
the registers and reset the PC to the start of the sequence. the registers and reset the PC to the start of the sequence.
@ -2149,12 +2161,7 @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
qemu_log_mask(LOG_UNIMP, "Unrecognized gUSA sequence %08x-%08x\n", qemu_log_mask(LOG_UNIMP, "Unrecognized gUSA sequence %08x-%08x\n",
pc, pc_end); pc, pc_end);
/* Restart with the EXCLUSIVE bit set, within a TB run via gen_restart_exclusive(ctx);
cpu_exec_step_atomic holding the exclusive lock. */
ctx->envflags |= TB_FLAG_GUSA_EXCLUSIVE;
gen_save_cpu_state(ctx, false);
gen_helper_exclusive(tcg_env);
ctx->base.is_jmp = DISAS_NORETURN;
/* We're not executing an instruction, but we must report one for the /* We're not executing an instruction, but we must report one for the
purposes of accounting within the TB. We might as well report the purposes of accounting within the TB. We might as well report the
@ -2242,12 +2249,22 @@ static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
if (unlikely(ctx->envflags & TB_FLAG_GUSA_MASK) if (unlikely(ctx->envflags & TB_FLAG_GUSA_MASK)
&& !(ctx->envflags & TB_FLAG_GUSA_EXCLUSIVE)) { && !(ctx->envflags & TB_FLAG_GUSA_EXCLUSIVE)) {
/* We're in an gUSA region, and we have not already fallen /*
back on using an exclusive region. Attempt to parse the * We're in an gUSA region, and we have not already fallen
region into a single supported atomic operation. Failure * back on using an exclusive region. Attempt to parse the
is handled within the parser by raising an exception to * region into a single supported atomic operation. Failure
retry using an exclusive region. */ * is handled within the parser by raising an exception to
* retry using an exclusive region.
*
* Parsing the region in one block conflicts with plugins,
* so always use exclusive mode if plugins enabled.
*/
if (ctx->base.plugin_enabled) {
gen_restart_exclusive(ctx);
ctx->base.pc_next += 2;
} else {
decode_gusa(ctx, env); decode_gusa(ctx, env);
}
return; return;
} }
#endif #endif

View file

@ -29,9 +29,9 @@ static inline void set_feature(CPUTriCoreState *env, int feature)
env->features |= 1ULL << feature; env->features |= 1ULL << feature;
} }
static gchar *tricore_gdb_arch_name(CPUState *cs) static const gchar *tricore_gdb_arch_name(CPUState *cs)
{ {
return g_strdup("tricore"); return "tricore";
} }
static void tricore_cpu_set_pc(CPUState *cs, vaddr value) static void tricore_cpu_set_pc(CPUState *cs, vaddr value)

View file

@ -28,33 +28,33 @@ class Aarch64SbsarefMachine(QemuSystemTest):
""" """
Flash volumes generated using: Flash volumes generated using:
- Fedora GNU Toolchain version 13.1.1 20230511 (Red Hat 13.1.1-2) - Fedora GNU Toolchain version 13.2.1 20230728 (Red Hat 13.2.1-1)
- Trusted Firmware-A - Trusted Firmware-A
https://github.com/ARM-software/arm-trusted-firmware/tree/c0d8ee38 https://github.com/ARM-software/arm-trusted-firmware/tree/7c3ff62d
- Tianocore EDK II - Tianocore EDK II
https://github.com/tianocore/edk2/tree/0f9283429dd4 https://github.com/tianocore/edk2/tree/0f9283429dd4
https://github.com/tianocore/edk2-non-osi/tree/f0bb00937ad6 https://github.com/tianocore/edk2/tree/ad1c0394b177
https://github.com/tianocore/edk2-platforms/tree/7880b92e2a04 https://github.com/tianocore/edk2-platforms/tree/d03a60523a60
""" """
# Secure BootRom (TF-A code) # Secure BootRom (TF-A code)
fs0_xz_url = ( fs0_xz_url = (
"https://fileserver.linaro.org/s/HrYMCjP7MEccjRP/" "https://fileserver.linaro.org/s/rE43RJyTfxPtBkc/"
"download/SBSA_FLASH0.fd.xz" "download/SBSA_FLASH0.fd.xz"
) )
fs0_xz_hash = "447eff64a90b84ce47703c6ec41fbfc25befaaea" fs0_xz_hash = "cdb8e4ffdaaa79292b7b465693f9e5fae6b7062d"
tar_xz_path = self.fetch_asset(fs0_xz_url, asset_hash=fs0_xz_hash) tar_xz_path = self.fetch_asset(fs0_xz_url, asset_hash=fs0_xz_hash)
archive.extract(tar_xz_path, self.workdir) archive.extract(tar_xz_path, self.workdir)
fs0_path = os.path.join(self.workdir, "SBSA_FLASH0.fd") fs0_path = os.path.join(self.workdir, "SBSA_FLASH0.fd")
# Non-secure rom (UEFI and EFI variables) # Non-secure rom (UEFI and EFI variables)
fs1_xz_url = ( fs1_xz_url = (
"https://fileserver.linaro.org/s/t8foNnMPz74DZZy/" "https://fileserver.linaro.org/s/AGWPDXbcqJTKS4R/"
"download/SBSA_FLASH1.fd.xz" "download/SBSA_FLASH1.fd.xz"
) )
fs1_xz_hash = "13a9a262953787c7fc5a9155dfaa26e703631e02" fs1_xz_hash = "411155ae6984334714dff08d5d628178e790c875"
tar_xz_path = self.fetch_asset(fs1_xz_url, asset_hash=fs1_xz_hash) tar_xz_path = self.fetch_asset(fs1_xz_url, asset_hash=fs1_xz_hash)
archive.extract(tar_xz_path, self.workdir) archive.extract(tar_xz_path, self.workdir)
fs1_path = os.path.join(self.workdir, "SBSA_FLASH1.fd") fs1_path = os.path.join(self.workdir, "SBSA_FLASH1.fd")
@ -75,7 +75,6 @@ class Aarch64SbsarefMachine(QemuSystemTest):
"sbsa-ref", "sbsa-ref",
) )
@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is not reliable')
def test_sbsaref_edk2_firmware(self): def test_sbsaref_edk2_firmware(self):
""" """
:avocado: tags=cpu:cortex-a57 :avocado: tags=cpu:cortex-a57
@ -144,7 +143,7 @@ class Aarch64SbsarefMachine(QemuSystemTest):
def test_sbsaref_alpine_linux_neoverse_n1(self): def test_sbsaref_alpine_linux_neoverse_n1(self):
""" """
:avocado: tags=cpu:max :avocado: tags=cpu:neoverse-n1
""" """
self.boot_alpine_linux("neoverse-n1") self.boot_alpine_linux("neoverse-n1")
@ -152,4 +151,54 @@ class Aarch64SbsarefMachine(QemuSystemTest):
""" """
:avocado: tags=cpu:max :avocado: tags=cpu:max
""" """
self.boot_alpine_linux("max,pauth-impdef=on") self.boot_alpine_linux("max")
# This tests the whole boot chain from EFI to Userspace
# We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots
def boot_openbsd73(self, cpu):
self.fetch_firmware()
img_url = (
"https://cdn.openbsd.org/pub/OpenBSD/7.3/arm64/miniroot73.img"
)
img_hash = "7fc2c75401d6f01fbfa25f4953f72ad7d7c18650056d30755c44b9c129b707e5"
img_path = self.fetch_asset(img_url, algorithm="sha256", asset_hash=img_hash)
self.vm.set_console()
self.vm.add_args(
"-cpu",
cpu,
"-drive",
f"file={img_path},format=raw",
"-device",
"virtio-rng-pci,rng=rng0",
"-object",
"rng-random,id=rng0,filename=/dev/urandom",
)
self.vm.launch()
wait_for_console_pattern(self,
"Welcome to the OpenBSD/arm64"
" 7.3 installation program.")
def test_sbsaref_openbsd73_cortex_a57(self):
"""
:avocado: tags=cpu:cortex-a57
"""
self.boot_openbsd73("cortex-a57")
def test_sbsaref_openbsd73_neoverse_n1(self):
"""
:avocado: tags=cpu:neoverse-n1
"""
self.boot_openbsd73("neoverse-n1")
def test_sbsaref_openbsd73_max(self):
"""
:avocado: tags=cpu:max
"""
self.boot_openbsd73("max")

View file

@ -16,9 +16,8 @@ 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))
RUNC ?= docker RUNC ?= $(if $(shell command -v docker), docker, podman)
ENGINE ?= auto DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py --engine $(RUNC)
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.$$$$)
DOCKER_SRC_COPY := $(BUILD_DIR)/docker-src.$(CUR_TIME) DOCKER_SRC_COPY := $(BUILD_DIR)/docker-src.$(CUR_TIME)
@ -158,7 +157,7 @@ $(foreach i,$(filter-out $(DOCKER_PARTIAL_IMAGES),$(DOCKER_IMAGES)), \
) )
docker: docker:
@echo 'Build QEMU and run tests inside Docker or Podman containers' @echo 'Build QEMU and run tests inside $(RUNC) containers'
@echo @echo
@echo 'Available targets:' @echo 'Available targets:'
@echo @echo
@ -198,8 +197,6 @@ docker:
@echo ' EXECUTABLE=<path> Include executable in image.' @echo ' EXECUTABLE=<path> Include executable in image.'
@echo ' EXTRA_FILES="<path> [... <path>]"' @echo ' EXTRA_FILES="<path> [... <path>]"'
@echo ' Include extra files in image.' @echo ' Include extra files in image.'
@echo ' ENGINE=auto/docker/podman'
@echo ' Specify which container engine to run.'
@echo ' REGISTRY=url Cache builds from registry (default:$(DOCKER_REGISTRY))' @echo ' REGISTRY=url Cache builds from registry (default:$(DOCKER_REGISTRY))'
docker-help: docker docker-help: docker

View file

@ -100,6 +100,7 @@ RUN apk update && \
sparse \ sparse \
spice-dev \ spice-dev \
spice-protocol \ spice-protocol \
swtpm \
tar \ tar \
tesseract-ocr \ tesseract-ocr \
usbredir-dev \ usbredir-dev \

View file

@ -107,6 +107,7 @@ RUN dnf distro-sync -y && \
socat \ socat \
spice-protocol \ spice-protocol \
spice-server-devel \ spice-server-devel \
swtpm \
systemd-devel \ systemd-devel \
systemtap-sdt-devel \ systemtap-sdt-devel \
tar \ tar \

View file

@ -55,6 +55,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
sed \ sed \
socat \ socat \
sparse \ sparse \
swtpm \
tar \ tar \
tesseract-ocr \ tesseract-ocr \
tesseract-ocr-eng \ tesseract-ocr-eng \

View file

@ -124,6 +124,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
sed \ sed \
socat \ socat \
sparse \ sparse \
swtpm \
systemtap-sdt-dev \ systemtap-sdt-dev \
tar \ tar \
tesseract-ocr \ tesseract-ocr \

View file

@ -55,6 +55,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
sed \ sed \
socat \ socat \
sparse \ sparse \
swtpm \
tar \ tar \
tesseract-ocr \ tesseract-ocr \
tesseract-ocr-eng \ tesseract-ocr-eng \

View file

@ -55,6 +55,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
sed \ sed \
socat \ socat \
sparse \ sparse \
swtpm \
tar \ tar \
tesseract-ocr \ tesseract-ocr \
tesseract-ocr-eng \ tesseract-ocr-eng \

View file

@ -55,6 +55,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
sed \ sed \
socat \ socat \
sparse \ sparse \
swtpm \
tar \ tar \
tesseract-ocr \ tesseract-ocr \
tesseract-ocr-eng \ tesseract-ocr-eng \

View file

@ -55,6 +55,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
sed \ sed \
socat \ socat \
sparse \ sparse \
swtpm \
tar \ tar \
tesseract-ocr \ tesseract-ocr \
tesseract-ocr-eng \ tesseract-ocr-eng \

View file

@ -55,6 +55,7 @@ exec "$@"\n' > /usr/bin/nosync && \
socat \ socat \
sparse \ sparse \
spice-protocol \ spice-protocol \
swtpm \
tar \ tar \
tesseract \ tesseract \
tesseract-langpack-eng \ tesseract-langpack-eng \

View file

@ -55,6 +55,7 @@ exec "$@"\n' > /usr/bin/nosync && \
socat \ socat \
sparse \ sparse \
spice-protocol \ spice-protocol \
swtpm \
tar \ tar \
tesseract \ tesseract \
tesseract-langpack-eng \ tesseract-langpack-eng \

View file

@ -118,6 +118,7 @@ exec "$@"\n' > /usr/bin/nosync && \
sparse \ sparse \
spice-protocol \ spice-protocol \
spice-server-devel \ spice-server-devel \
swtpm \
systemd-devel \ systemd-devel \
systemtap-sdt-devel \ systemtap-sdt-devel \
tar \ tar \

View file

@ -100,6 +100,7 @@ RUN zypper update -y && \
socat \ socat \
sparse \ sparse \
spice-protocol-devel \ spice-protocol-devel \
swtpm \
systemd-devel \ systemd-devel \
systemtap-sdt-devel \ systemtap-sdt-devel \
tar \ tar \

View file

@ -124,6 +124,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
sed \ sed \
socat \ socat \
sparse \ sparse \
swtpm \
systemtap-sdt-dev \ systemtap-sdt-dev \
tar \ tar \
tesseract-ocr \ tesseract-ocr \

@ -1 +1 @@
Subproject commit e3ed1e5da101943e53d8d89424e17b22120743f5 Subproject commit 36bc517161c45ead20224d47f2dc4fa428af6724

View file

@ -110,6 +110,7 @@ packages:
- spice-protocol - spice-protocol
- spice-server - spice-server
- ssh-client - ssh-client
- swtpm
- systemd - systemd
- tar - tar
- tesseract - tesseract