* [PULL 01/35] ci: clean-up remaining bits of armhf builds.
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 02/35] scripts/ci/setup: regenerate yaml Alex Bennée
` (34 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Bennée, Philippe Mathieu-Daudé, Richard Henderson,
Thomas Huth
We no longer need to support 32 bit builds and we missed this while
cleaning up.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20251027110344.2289945-2-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/docs/devel/testing/ci-jobs.rst.inc b/docs/devel/testing/ci-jobs.rst.inc
index f1c541cc25b..b92d372a0a9 100644
--- a/docs/devel/testing/ci-jobs.rst.inc
+++ b/docs/devel/testing/ci-jobs.rst.inc
@@ -168,13 +168,6 @@ If you've got access to an aarch64 host that can be used as a gitlab-CI
runner, you can set this variable to enable the tests that require this
kind of host. The runner should be tagged with "aarch64".
-AARCH32_RUNNER_AVAILABLE
-~~~~~~~~~~~~~~~~~~~~~~~~
-If you've got access to an armhf host or an arch64 host that can run
-aarch32 EL0 code to be used as a gitlab-CI runner, you can set this
-variable to enable the tests that require this kind of host. The
-runner should be tagged with "aarch32".
-
S390X_RUNNER_AVAILABLE
~~~~~~~~~~~~~~~~~~~~~~
If you've got access to an IBM Z host that can be used as a gitlab-CI
diff --git a/scripts/ci/setup/ubuntu/build-environment.yml b/scripts/ci/setup/ubuntu/build-environment.yml
index 0f8ec5fab04..1c517c74f74 100644
--- a/scripts/ci/setup/ubuntu/build-environment.yml
+++ b/scripts/ci/setup/ubuntu/build-environment.yml
@@ -19,12 +19,6 @@
- '((ansible_version.major == 2) and (ansible_version.minor >= 8)) or (ansible_version.major >= 3)'
msg: "Unsuitable ansible version, please use version 2.8.0 or later"
- - name: Add armhf foreign architecture to aarch64 hosts
- command: dpkg --add-architecture armhf
- when:
- - ansible_facts['distribution'] == 'Ubuntu'
- - ansible_facts['architecture'] == 'aarch64'
-
- name: Update apt cache / upgrade packages via apt
apt:
update_cache: yes
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 02/35] scripts/ci/setup: regenerate yaml
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
2025-10-29 15:50 ` [PULL 01/35] ci: clean-up remaining bits of armhf builds Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 03/35] scripts/ci: move build-environment.yaml up a level Alex Bennée
` (33 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Bennée, Manos Pitsidianakis,
Philippe Mathieu-Daudé, Thomas Huth
We inadvertently updated the base libvirt-ci project which has
resulted in changes. Make sure the output matches what we generate.
Fixes: 0d4fb8f746d (configure: set the bindgen cross target)
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-ID: <20251027110344.2289945-3-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/scripts/ci/setup/ubuntu/ubuntu-2404-aarch64.yaml b/scripts/ci/setup/ubuntu/ubuntu-2404-aarch64.yaml
index ce632d97108..70063db198e 100644
--- a/scripts/ci/setup/ubuntu/ubuntu-2404-aarch64.yaml
+++ b/scripts/ci/setup/ubuntu/ubuntu-2404-aarch64.yaml
@@ -26,7 +26,7 @@ packages:
- git
- hostname
- libaio-dev
- - libasan6
+ - libasan8
- libasound2-dev
- libattr1-dev
- libbpf-dev
@@ -37,7 +37,7 @@ packages:
- libcap-ng-dev
- libcapstone-dev
- libcbor-dev
- - libclang-dev
+ - libclang-rt-dev
- libcmocka-dev
- libcurl4-gnutls-dev
- libdaxctl-dev
diff --git a/scripts/ci/setup/ubuntu/ubuntu-2404-s390x.yaml b/scripts/ci/setup/ubuntu/ubuntu-2404-s390x.yaml
index f45f75c9602..4f1a49be34a 100644
--- a/scripts/ci/setup/ubuntu/ubuntu-2404-s390x.yaml
+++ b/scripts/ci/setup/ubuntu/ubuntu-2404-s390x.yaml
@@ -26,7 +26,7 @@ packages:
- git
- hostname
- libaio-dev
- - libasan6
+ - libasan8
- libasound2-dev
- libattr1-dev
- libbpf-dev
@@ -37,7 +37,7 @@ packages:
- libcap-ng-dev
- libcapstone-dev
- libcbor-dev
- - libclang-dev
+ - libclang-rt-dev
- libcmocka-dev
- libcurl4-gnutls-dev
- libdaxctl-dev
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 03/35] scripts/ci: move build-environment.yaml up a level
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
2025-10-29 15:50 ` [PULL 01/35] ci: clean-up remaining bits of armhf builds Alex Bennée
2025-10-29 15:50 ` [PULL 02/35] scripts/ci/setup: regenerate yaml Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 04/35] scripts/ci: allow both Ubuntu or Debian to run upgrade Alex Bennée
` (32 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Bennée, Manos Pitsidianakis,
Philippe Mathieu-Daudé, Thomas Huth
We can share the setup of the build environment with multiple
operating systems as we just need to check the YAML for each env is
present in the directory structure.
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-ID: <20251027110344.2289945-4-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/scripts/ci/setup/ubuntu/build-environment.yml b/scripts/ci/setup/build-environment.yml
similarity index 81%
rename from scripts/ci/setup/ubuntu/build-environment.yml
rename to scripts/ci/setup/build-environment.yml
index 1c517c74f74..66bde188755 100644
--- a/scripts/ci/setup/ubuntu/build-environment.yml
+++ b/scripts/ci/setup/build-environment.yml
@@ -27,18 +27,24 @@
- ansible_facts['distribution'] == 'Ubuntu'
# the package lists are updated by "make lcitool-refresh"
- - name: Include package lists based on OS and architecture
- include_vars:
- file: "ubuntu-2404-{{ ansible_facts['architecture'] }}.yaml"
+ - name: Define package list file path
+ set_fact:
+ package_file: "ubuntu/ubuntu-2404-{{ ansible_facts['architecture'] }}.yaml"
when:
- ansible_facts['distribution'] == 'Ubuntu'
- ansible_facts['distribution_version'] == '24.04'
+ - name: Include package lists based on OS and architecture
+ include_vars:
+ file: "{{ package_file }}"
+ when:
+ - package_file is exists
+
- name: Install packages for QEMU on Ubuntu 24.04
package:
name: "{{ packages }}"
when:
- - ansible_facts['distribution'] == 'Ubuntu'
- - ansible_facts['distribution_version'] == '24.04'
+ - package_file is exists
+ - packages is defined
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 04/35] scripts/ci: allow both Ubuntu or Debian to run upgrade
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (2 preceding siblings ...)
2025-10-29 15:50 ` [PULL 03/35] scripts/ci: move build-environment.yaml up a level Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 05/35] tests/lcitool: generate a yaml file for the ppc64le runner Alex Bennée
` (31 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Bennée, Manos Pitsidianakis,
Philippe Mathieu-Daudé, Thomas Huth
There is no practical difference between the systems when it comes to
updating the installed system.
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-ID: <20251027110344.2289945-5-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/scripts/ci/setup/build-environment.yml b/scripts/ci/setup/build-environment.yml
index 66bde188755..253d0b759bc 100644
--- a/scripts/ci/setup/build-environment.yml
+++ b/scripts/ci/setup/build-environment.yml
@@ -24,7 +24,7 @@
update_cache: yes
upgrade: yes
when:
- - ansible_facts['distribution'] == 'Ubuntu'
+ - ansible_facts['distribution'] in ['Ubuntu', 'Debian']
# the package lists are updated by "make lcitool-refresh"
- name: Define package list file path
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 05/35] tests/lcitool: generate a yaml file for the ppc64le runner
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (3 preceding siblings ...)
2025-10-29 15:50 ` [PULL 04/35] scripts/ci: allow both Ubuntu or Debian to run upgrade Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 06/35] scripts/ci: modify gitlab runner deb setup Alex Bennée
` (30 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Bennée, Manos Pitsidianakis,
Philippe Mathieu-Daudé, Thomas Huth
Unlike the Aarch64 runners this comes with pure Debian out of the box.
We need a minor tweak to build-environment to deal with the
differences in naming convention.
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-ID: <20251027110344.2289945-6-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/scripts/ci/setup/build-environment.yml b/scripts/ci/setup/build-environment.yml
index 253d0b759bc..528150dce78 100644
--- a/scripts/ci/setup/build-environment.yml
+++ b/scripts/ci/setup/build-environment.yml
@@ -27,20 +27,26 @@
- ansible_facts['distribution'] in ['Ubuntu', 'Debian']
# the package lists are updated by "make lcitool-refresh"
- - name: Define package list file path
+ - name: Define package list file path for Ubuntu
set_fact:
package_file: "ubuntu/ubuntu-2404-{{ ansible_facts['architecture'] }}.yaml"
when:
- ansible_facts['distribution'] == 'Ubuntu'
- ansible_facts['distribution_version'] == '24.04'
+ - name: Define package list file path for Debian
+ set_fact:
+ package_file: "debian/debian-{{ ansible_facts['distribution_major_version'] }}-{{ ansible_facts['architecture'] }}.yaml"
+ when:
+ - ansible_facts['distribution'] == 'Debian'
+
- name: Include package lists based on OS and architecture
include_vars:
file: "{{ package_file }}"
when:
- package_file is exists
- - name: Install packages for QEMU on Ubuntu 24.04
+ - name: Install packages for QEMU on Ubuntu/Debian
package:
name: "{{ packages }}"
when:
diff --git a/scripts/ci/setup/debian/debian-13-ppc64le.yaml b/scripts/ci/setup/debian/debian-13-ppc64le.yaml
new file mode 100644
index 00000000000..e29c9c18403
--- /dev/null
+++ b/scripts/ci/setup/debian/debian-13-ppc64le.yaml
@@ -0,0 +1,134 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+# $ lcitool variables --host-arch ppc64le debian-13 qemu
+#
+# https://gitlab.com/libvirt/libvirt-ci
+
+packages:
+ - bash
+ - bc
+ - bindgen
+ - bison
+ - bsdextrautils
+ - bzip2
+ - ca-certificates
+ - ccache
+ - clang
+ - dbus
+ - debianutils
+ - diffutils
+ - exuberant-ctags
+ - findutils
+ - flex
+ - gcc
+ - gcovr
+ - gettext
+ - git
+ - hostname
+ - libaio-dev
+ - libasan8
+ - libasound2-dev
+ - libattr1-dev
+ - libbpf-dev
+ - libbrlapi-dev
+ - libbz2-dev
+ - libc6-dev
+ - libcacard-dev
+ - libcap-ng-dev
+ - libcapstone-dev
+ - libcbor-dev
+ - libclang-rt-dev
+ - libcmocka-dev
+ - libcurl4-gnutls-dev
+ - libdaxctl-dev
+ - libdrm-dev
+ - libepoxy-dev
+ - libfdt-dev
+ - libffi-dev
+ - libfuse3-dev
+ - libgbm-dev
+ - libgcrypt20-dev
+ - libglib2.0-dev
+ - libglusterfs-dev
+ - libgnutls28-dev
+ - libgtk-3-dev
+ - libgtk-vnc-2.0-dev
+ - libibverbs-dev
+ - libiscsi-dev
+ - libjemalloc-dev
+ - libjpeg62-turbo-dev
+ - libjson-c-dev
+ - liblttng-ust-dev
+ - liblzo2-dev
+ - libncursesw5-dev
+ - libnfs-dev
+ - libnuma-dev
+ - libpam0g-dev
+ - libpcre2-dev
+ - libpipewire-0.3-dev
+ - libpixman-1-dev
+ - libpng-dev
+ - libpulse-dev
+ - librbd-dev
+ - librdmacm-dev
+ - libsasl2-dev
+ - libsdl2-dev
+ - libsdl2-image-dev
+ - libseccomp-dev
+ - libselinux1-dev
+ - libslirp-dev
+ - libsnappy-dev
+ - libsndio-dev
+ - libspice-protocol-dev
+ - libspice-server-dev
+ - libssh-dev
+ - libstd-rust-dev
+ - libsystemd-dev
+ - libtasn1-6-dev
+ - libubsan1
+ - libudev-dev
+ - liburing-dev
+ - libusb-1.0-0-dev
+ - libusbredirhost-dev
+ - libvdeplug-dev
+ - libvirglrenderer-dev
+ - libvte-2.91-dev
+ - libxdp-dev
+ - libzstd-dev
+ - llvm
+ - locales
+ - make
+ - mtools
+ - multipath-tools
+ - ncat
+ - nettle-dev
+ - ninja-build
+ - openssh-client
+ - pkgconf
+ - python3
+ - python3-numpy
+ - python3-opencv
+ - python3-pillow
+ - python3-pip
+ - python3-setuptools
+ - python3-sphinx
+ - python3-sphinx-rtd-theme
+ - python3-tomli
+ - python3-venv
+ - python3-wheel
+ - python3-yaml
+ - rpm2cpio
+ - rustc
+ - sed
+ - socat
+ - sparse
+ - swtpm
+ - systemtap-sdt-dev
+ - tar
+ - tesseract-ocr
+ - tesseract-ocr-eng
+ - vulkan-tools
+ - xorriso
+ - zlib1g-dev
+ - zstd
+
diff --git a/tests/lcitool/refresh b/tests/lcitool/refresh
index 056cfb6e9d7..7fbdf6f340b 100755
--- a/tests/lcitool/refresh
+++ b/tests/lcitool/refresh
@@ -272,6 +272,7 @@ try:
#
generate_yaml("ubuntu", "ubuntu-2404", "aarch64")
generate_yaml("ubuntu", "ubuntu-2404", "s390x")
+ generate_yaml("debian", "debian-13", "ppc64le")
sys.exit(0)
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 06/35] scripts/ci: modify gitlab runner deb setup
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (4 preceding siblings ...)
2025-10-29 15:50 ` [PULL 05/35] tests/lcitool: generate a yaml file for the ppc64le runner Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 07/35] plugins: add types for callbacks related to certain discontinuities Alex Bennée
` (29 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Bennée, Manos Pitsidianakis,
Philippe Mathieu-Daudé, Thomas Huth
Both Debian and Ubuntu are setup the same way.
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-ID: <20251027110344.2289945-7-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/scripts/ci/setup/gitlab-runner.yml b/scripts/ci/setup/gitlab-runner.yml
index 7025935487a..76aeaf4ee95 100644
--- a/scripts/ci/setup/gitlab-runner.yml
+++ b/scripts/ci/setup/gitlab-runner.yml
@@ -56,12 +56,12 @@
url: "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh"
mode: 0755
when:
- - ansible_facts['distribution'] == 'Ubuntu'
+ - ansible_facts['distribution'] in ['Ubuntu', 'Debian']
- name: Run gitlab-runner repo setup script (DEB)
shell: "/root/script.deb.sh"
when:
- - ansible_facts['distribution'] == 'Ubuntu'
+ - ansible_facts['distribution'] in ['Ubuntu', 'Debian']
- name: Install gitlab-runner (DEB)
ansible.builtin.apt:
@@ -69,7 +69,7 @@
update_cache: yes
state: present
when:
- - ansible_facts['distribution'] == 'Ubuntu'
+ - ansible_facts['distribution'] in ['Ubuntu', 'Debian']
# RPM setup
- name: Get gitlab-runner repo setup script (RPM)
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 07/35] plugins: add types for callbacks related to certain discontinuities
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (5 preceding siblings ...)
2025-10-29 15:50 ` [PULL 06/35] scripts/ci: modify gitlab runner deb setup Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 08/35] plugins: add API for registering discontinuity callbacks Alex Bennée
` (28 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Pierrick Bouvier, Richard Henderson,
Alex Bennée
From: Julian Ganz <neither@nut.email>
The plugin API allows registration of callbacks for a variety of VCPU
related events, such as VCPU reset, idle and resume. However, traps of
any kind, i.e. interrupts or exceptions, were previously not covered.
These kinds of events are arguably quite significant and usually go hand
in hand with a PC discontinuity. On most platforms, the discontinuity
also includes a transition from some "mode" to another. Thus, plugins
for the analysis of (virtualized) embedded systems may benefit from or
even require the possiblity to perform work on the occurance of an
interrupt or exception.
This change introduces the concept of such a discontinuity event in the
form of an enumeration. Currently only traps are covered. Specifically
we (loosely) define interrupts, exceptions and host calls across all
platforms. In addition, this change introduces a type to use for
callback functions related to such events. Since possible modes and the
enumeration of interupts and exceptions vary greatly between different
architectures, the callback type only receives the VCPU id, the type of
event as well as the old and new PC.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-8-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index f355c7cb8ab..8cf20cd96f7 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -59,6 +59,7 @@ union qemu_plugin_cb_sig {
qemu_plugin_udata_cb_t udata;
qemu_plugin_vcpu_simple_cb_t vcpu_simple;
qemu_plugin_vcpu_udata_cb_t vcpu_udata;
+ qemu_plugin_vcpu_discon_cb_t vcpu_discon;
qemu_plugin_vcpu_tb_trans_cb_t vcpu_tb_trans;
qemu_plugin_vcpu_mem_cb_t vcpu_mem;
qemu_plugin_vcpu_syscall_cb_t vcpu_syscall;
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index c450106af18..08bf366e363 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -161,6 +161,50 @@ typedef void (*qemu_plugin_vcpu_simple_cb_t)(qemu_plugin_id_t id,
typedef void (*qemu_plugin_vcpu_udata_cb_t)(unsigned int vcpu_index,
void *userdata);
+
+/**
+ * enum qemu_plugin_discon_type - type of a (potential) PC discontinuity
+ *
+ * @QEMU_PLUGIN_DISCON_INTERRUPT: an interrupt, defined across all architectures
+ * as an asynchronous event, usually originating
+ * from outside the CPU
+ * @QEMU_PLUGIN_DISCON_EXCEPTION: an exception, defined across all architectures
+ * as a synchronous event in response to a
+ * specific instruction being executed
+ * @QEMU_PLUGIN_DISCON_HOSTCALL: a host call, functionally a special kind of
+ * exception that is not handled by code run by
+ * the vCPU but machinery outside the vCPU
+ * @QEMU_PLUGIN_DISCON_ALL: all types of disconinuity events currently covered
+ */
+enum qemu_plugin_discon_type {
+ QEMU_PLUGIN_DISCON_INTERRUPT = 1 << 0,
+ QEMU_PLUGIN_DISCON_EXCEPTION = 1 << 1,
+ QEMU_PLUGIN_DISCON_HOSTCALL = 1 << 2,
+ QEMU_PLUGIN_DISCON_ALL = -1
+};
+
+/**
+ * typedef qemu_plugin_vcpu_discon_cb_t - vcpu discontinuity callback
+ * @id: plugin ID
+ * @vcpu_index: the current vcpu context
+ * @type: the type of discontinuity
+ * @from_pc: the source of the discontinuity, e.g. the PC before the
+ * transition
+ * @to_pc: the PC pointing to the next instruction to be executed
+ *
+ * The exact semantics of @from_pc depends on the @type of discontinuity. For
+ * interrupts, @from_pc will point to the next instruction which would have
+ * been executed. For exceptions and host calls, @from_pc will point to the
+ * instruction that caused the exception or issued the host call. Note that
+ * in the case of exceptions, the instruction may not be retired and thus not
+ * observable via general instruction exec callbacks. The same may be the case
+ * for some host calls such as hypervisor call "exceptions".
+ */
+typedef void (*qemu_plugin_vcpu_discon_cb_t)(qemu_plugin_id_t id,
+ unsigned int vcpu_index,
+ enum qemu_plugin_discon_type type,
+ uint64_t from_pc, uint64_t to_pc);
+
/**
* qemu_plugin_uninstall() - Uninstall a plugin
* @id: this plugin's opaque ID
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 08/35] plugins: add API for registering discontinuity callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (6 preceding siblings ...)
2025-10-29 15:50 ` [PULL 07/35] plugins: add types for callbacks related to certain discontinuities Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 09/35] plugins: add hooks for new discontinuity related callbacks Alex Bennée
` (27 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Pierrick Bouvier, Richard Henderson,
Alex Bennée, Alexandre Iooss, Mahmoud Mandour
From: Julian Ganz <neither@nut.email>
The plugin API allows registration of callbacks for a variety of VCPU
related events, such as VCPU reset, idle and resume. In addition to
those events, we recently defined discontinuity events, which include
traps.
This change introduces a function to register callbacks for these
events. We define one distinct plugin event type for each type of
discontinuity, granting fine control to plugins in term of which events
they receive.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-9-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/include/qemu/plugin-event.h b/include/qemu/plugin-event.h
index 7056d8427b7..1100dae2123 100644
--- a/include/qemu/plugin-event.h
+++ b/include/qemu/plugin-event.h
@@ -20,6 +20,9 @@ enum qemu_plugin_event {
QEMU_PLUGIN_EV_VCPU_SYSCALL_RET,
QEMU_PLUGIN_EV_FLUSH,
QEMU_PLUGIN_EV_ATEXIT,
+ QEMU_PLUGIN_EV_VCPU_INTERRUPT,
+ QEMU_PLUGIN_EV_VCPU_EXCEPTION,
+ QEMU_PLUGIN_EV_VCPU_HOSTCALL,
QEMU_PLUGIN_EV_MAX, /* total number of plugin events we support */
};
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index 08bf366e363..60de4fdd3fa 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -281,6 +281,22 @@ QEMU_PLUGIN_API
void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
qemu_plugin_vcpu_simple_cb_t cb);
+/**
+ * qemu_plugin_register_vcpu_discon_cb() - register a discontinuity callback
+ * @id: plugin ID
+ * @type: types of discontinuities for which to call the callback
+ * @cb: callback function
+ *
+ * The @cb function is called every time a vCPU receives a discontinuity event
+ * of the specified type(s), after the vCPU was prepared to handle the event.
+ * Preparation entails updating the PC, usually to some interrupt handler or
+ * trap vector entry.
+ */
+QEMU_PLUGIN_API
+void qemu_plugin_register_vcpu_discon_cb(qemu_plugin_id_t id,
+ enum qemu_plugin_discon_type type,
+ qemu_plugin_vcpu_discon_cb_t cb);
+
/** struct qemu_plugin_tb - Opaque handle for a translation block */
struct qemu_plugin_tb;
/** struct qemu_plugin_insn - Opaque handle for a translated instruction */
diff --git a/plugins/core.c b/plugins/core.c
index ead09fd2f1e..40d001d39ad 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -569,6 +569,21 @@ void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_RESUME, cb);
}
+void qemu_plugin_register_vcpu_discon_cb(qemu_plugin_id_t id,
+ enum qemu_plugin_discon_type type,
+ qemu_plugin_vcpu_discon_cb_t cb)
+{
+ if (type & QEMU_PLUGIN_DISCON_INTERRUPT) {
+ plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_INTERRUPT, cb);
+ }
+ if (type & QEMU_PLUGIN_DISCON_EXCEPTION) {
+ plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_EXCEPTION, cb);
+ }
+ if (type & QEMU_PLUGIN_DISCON_HOSTCALL) {
+ plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_HOSTCALL, cb);
+ }
+}
+
void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
qemu_plugin_simple_cb_t cb)
{
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 09/35] plugins: add hooks for new discontinuity related callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (7 preceding siblings ...)
2025-10-29 15:50 ` [PULL 08/35] plugins: add API for registering discontinuity callbacks Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 10/35] contrib/plugins: add plugin showcasing new dicontinuity related API Alex Bennée
` (26 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
From: Julian Ganz <neither@nut.email>
The plugin API allows registration of callbacks for a variety of VCPU
related events, such as VCPU reset, idle and resume. In addition, we
recently introduced API for registering callbacks for discontinuity
events, specifically for interrupts, exceptions and host calls.
This change introduces the corresponding hooks called from target
specific code inside qemu.
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-10-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index 8cf20cd96f7..cea0a68858b 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -161,6 +161,9 @@ void qemu_plugin_vcpu_exit_hook(CPUState *cpu);
void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb);
void qemu_plugin_vcpu_idle_cb(CPUState *cpu);
void qemu_plugin_vcpu_resume_cb(CPUState *cpu);
+void qemu_plugin_vcpu_interrupt_cb(CPUState *cpu, uint64_t from);
+void qemu_plugin_vcpu_exception_cb(CPUState *cpu, uint64_t from);
+void qemu_plugin_vcpu_hostcall_cb(CPUState *cpu, uint64_t from);
void
qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1,
uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5,
@@ -258,6 +261,15 @@ static inline void qemu_plugin_vcpu_idle_cb(CPUState *cpu)
static inline void qemu_plugin_vcpu_resume_cb(CPUState *cpu)
{ }
+static inline void qemu_plugin_vcpu_interrupt_cb(CPUState *cpu, uint64_t from)
+{ }
+
+static inline void qemu_plugin_vcpu_exception_cb(CPUState *cpu, uint64_t from)
+{ }
+
+static inline void qemu_plugin_vcpu_hostcall_cb(CPUState *cpu, uint64_t from)
+{ }
+
static inline void
qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5, uint64_t a6,
diff --git a/plugins/core.c b/plugins/core.c
index 40d001d39ad..35a252d2729 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -105,6 +105,30 @@ static void plugin_vcpu_cb__simple(CPUState *cpu, enum qemu_plugin_event ev)
}
}
+/*
+ * Disable CFI checks.
+ * The callback function has been loaded from an external library so we do not
+ * have type information
+ */
+QEMU_DISABLE_CFI
+static void plugin_vcpu_cb__discon(CPUState *cpu,
+ enum qemu_plugin_event ev,
+ enum qemu_plugin_discon_type type,
+ uint64_t from)
+{
+ struct qemu_plugin_cb *cb, *next;
+ uint64_t to = cpu->cc->get_pc(cpu);
+
+ if (cpu->cpu_index < plugin.num_vcpus) {
+ /* iterate safely; plugins might uninstall themselves at any time */
+ QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
+ qemu_plugin_vcpu_discon_cb_t func = cb->f.vcpu_discon;
+
+ func(cb->ctx->id, cpu->cpu_index, type, from, to);
+ }
+ }
+}
+
/*
* Disable CFI checks.
* The callback function has been loaded from an external library so we do not
@@ -557,6 +581,24 @@ void qemu_plugin_vcpu_resume_cb(CPUState *cpu)
}
}
+void qemu_plugin_vcpu_interrupt_cb(CPUState *cpu, uint64_t from)
+{
+ plugin_vcpu_cb__discon(cpu, QEMU_PLUGIN_EV_VCPU_INTERRUPT,
+ QEMU_PLUGIN_DISCON_INTERRUPT, from);
+}
+
+void qemu_plugin_vcpu_exception_cb(CPUState *cpu, uint64_t from)
+{
+ plugin_vcpu_cb__discon(cpu, QEMU_PLUGIN_EV_VCPU_EXCEPTION,
+ QEMU_PLUGIN_DISCON_EXCEPTION, from);
+}
+
+void qemu_plugin_vcpu_hostcall_cb(CPUState *cpu, uint64_t from)
+{
+ plugin_vcpu_cb__discon(cpu, QEMU_PLUGIN_EV_VCPU_HOSTCALL,
+ QEMU_PLUGIN_DISCON_HOSTCALL, from);
+}
+
void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
qemu_plugin_vcpu_simple_cb_t cb)
{
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 10/35] contrib/plugins: add plugin showcasing new dicontinuity related API
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (8 preceding siblings ...)
2025-10-29 15:50 ` [PULL 09/35] plugins: add hooks for new discontinuity related callbacks Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 11/35] target/alpha: call plugin trap callbacks Alex Bennée
` (25 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Pierrick Bouvier, Alex Bennée, Alexandre Iooss,
Mahmoud Mandour
From: Julian Ganz <neither@nut.email>
We recently introduced new plugin API for registration of discontinuity
related callbacks. This change introduces a minimal plugin showcasing
the new API. It simply counts the occurances of interrupts, exceptions
and host calls per CPU and reports the counts when exitting.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-11-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/docs/about/emulation.rst b/docs/about/emulation.rst
index 8a5e128f677..92c219119e8 100644
--- a/docs/about/emulation.rst
+++ b/docs/about/emulation.rst
@@ -1015,6 +1015,14 @@ interesting to generate them around a particular point of execution::
# generate trace around init execution (2 seconds):
$ uftrace dump --chrome --time-range=1753122320~1753122322 > init.json
+Count traps
+...........
+
+``contrib/plugins/traps.c``
+
+This plugin counts the number of interrupts (asyncronous events), exceptions
+(synchronous events) and host calls (e.g. semihosting) per cpu.
+
Other emulation features
------------------------
diff --git a/contrib/plugins/traps.c b/contrib/plugins/traps.c
new file mode 100644
index 00000000000..d5ddc0f3dd6
--- /dev/null
+++ b/contrib/plugins/traps.c
@@ -0,0 +1,83 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2025, Julian Ganz <neither@nut.email>
+ *
+ * Traps - count traps
+ *
+ * Count the number of interrupts (asyncronous events), exceptions (synchronous
+ * events) and host calls (e.g. semihosting) per cpu and report those counts on
+ * exit.
+ */
+
+#include <stdio.h>
+
+#include <qemu-plugin.h>
+
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
+typedef struct {
+ uint64_t interrupts;
+ uint64_t exceptions;
+ uint64_t hostcalls;
+} TrapCounters;
+
+static struct qemu_plugin_scoreboard *traps;
+
+static void vcpu_discon(qemu_plugin_id_t id, unsigned int vcpu_index,
+ enum qemu_plugin_discon_type type, uint64_t from_pc,
+ uint64_t to_pc)
+{
+ TrapCounters *rec = qemu_plugin_scoreboard_find(traps, vcpu_index);
+ switch (type) {
+ case QEMU_PLUGIN_DISCON_INTERRUPT:
+ rec->interrupts++;
+ break;
+ case QEMU_PLUGIN_DISCON_EXCEPTION:
+ rec->exceptions++;
+ break;
+ case QEMU_PLUGIN_DISCON_HOSTCALL:
+ rec->hostcalls++;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+}
+
+static void plugin_exit(qemu_plugin_id_t id, void *p)
+{
+ g_autoptr(GString) report;
+ report = g_string_new("VCPU, interrupts, exceptions, hostcalls\n");
+ int max_vcpus = qemu_plugin_num_vcpus();
+ int vcpu;
+
+ for (vcpu = 0; vcpu < max_vcpus; vcpu++) {
+ TrapCounters *rec = qemu_plugin_scoreboard_find(traps, vcpu);
+ g_string_append_printf(report,
+ "% 4d, % 10"PRId64", % 10"PRId64", % 10"PRId64
+ "\n", vcpu, rec->interrupts, rec->exceptions,
+ rec->hostcalls);
+ }
+
+ qemu_plugin_outs(report->str);
+ qemu_plugin_scoreboard_free(traps);
+}
+
+QEMU_PLUGIN_EXPORT
+int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,
+ int argc, char **argv)
+{
+ if (!info->system_emulation) {
+ qemu_plugin_outs("Note: interrupts are only reported in system"
+ " emulation mode.");
+ }
+
+ traps = qemu_plugin_scoreboard_new(sizeof(TrapCounters));
+
+ qemu_plugin_register_vcpu_discon_cb(id, QEMU_PLUGIN_DISCON_ALL,
+ vcpu_discon);
+
+ qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
+
+ return 0;
+}
diff --git a/contrib/plugins/meson.build b/contrib/plugins/meson.build
index 7eb3629c95d..eb944b5159a 100644
--- a/contrib/plugins/meson.build
+++ b/contrib/plugins/meson.build
@@ -1,6 +1,6 @@
contrib_plugins = ['bbv', 'cache', 'cflow', 'drcov', 'execlog', 'hotblocks',
'hotpages', 'howvec', 'hwprofile', 'ips', 'stoptrigger',
- 'uftrace']
+ 'traps', 'uftrace']
if host_os != 'windows'
# lockstep uses socket.h
contrib_plugins += 'lockstep'
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 11/35] target/alpha: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (9 preceding siblings ...)
2025-10-29 15:50 ` [PULL 10/35] contrib/plugins: add plugin showcasing new dicontinuity related API Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 12/35] target/arm: " Alex Bennée
` (24 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Julian Ganz, Richard Henderson, Alex Bennée
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for Alpha targets.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-12-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index 096eac34458..a9af52a928f 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -27,6 +27,7 @@
#include "exec/helper-proto.h"
#include "qemu/qemu-print.h"
#include "system/memory.h"
+#include "qemu/plugin.h"
#define CONVERT_BIT(X, SRC, DST) \
@@ -328,6 +329,7 @@ void alpha_cpu_do_interrupt(CPUState *cs)
{
CPUAlphaState *env = cpu_env(cs);
int i = cs->exception_index;
+ uint64_t last_pc = env->pc;
if (qemu_loglevel_mask(CPU_LOG_INT)) {
static int count;
@@ -431,6 +433,17 @@ void alpha_cpu_do_interrupt(CPUState *cs)
/* Switch to PALmode. */
env->flags |= ENV_FLAG_PAL_MODE;
+
+ switch (i) {
+ case EXCP_SMP_INTERRUPT:
+ case EXCP_CLK_INTERRUPT:
+ case EXCP_DEV_INTERRUPT:
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
+ break;
+ default:
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
+ break;
+ }
}
bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 12/35] target/arm: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (10 preceding siblings ...)
2025-10-29 15:50 ` [PULL 11/35] target/alpha: call plugin trap callbacks Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 13/35] target/avr: " Alex Bennée
` (23 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Richard Henderson, Alex Bennée, Peter Maydell,
open list:ARM TCG CPUs
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for ARM (and Aarch64) targets. We decided to
treat the (V)IRQ, (VI/VF)NMI, (V)FIQ and VSERR exceptions as interrupts
since they are, presumably, async in nature.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-13-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/arm/internals.h b/target/arm/internals.h
index f86f421a3db..6fbf7e1ca49 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -375,6 +375,7 @@ static inline int r14_bank_number(int mode)
void arm_cpu_register(const ARMCPUInfo *info);
+void arm_do_plugin_vcpu_discon_cb(CPUState *cs, uint64_t from);
void register_cp_regs_for_features(ARMCPU *cpu);
void init_cpreg_list(ARMCPU *cpu);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2ef9c178147..ef6435c3efb 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -34,6 +34,7 @@
#endif
#include "cpregs.h"
#include "target/arm/gtimer.h"
+#include "qemu/plugin.h"
#define HELPER_H "tcg/helper.h"
#include "exec/helper-proto.h.inc"
@@ -8783,6 +8784,24 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
}
}
+void arm_do_plugin_vcpu_discon_cb(CPUState *cs, uint64_t from)
+{
+ switch (cs->exception_index) {
+ case EXCP_IRQ:
+ case EXCP_VIRQ:
+ case EXCP_NMI:
+ case EXCP_VINMI:
+ case EXCP_FIQ:
+ case EXCP_VFIQ:
+ case EXCP_VFNMI:
+ case EXCP_VSERR:
+ qemu_plugin_vcpu_interrupt_cb(cs, from);
+ break;
+ default:
+ qemu_plugin_vcpu_exception_cb(cs, from);
+ }
+}
+
static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
{
/*
@@ -9473,6 +9492,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
unsigned int new_el = env->exception.target_el;
+ uint64_t last_pc = cs->cc->get_pc(cs);
assert(!arm_feature(env, ARM_FEATURE_M));
@@ -9489,6 +9509,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
if (tcg_enabled() && arm_is_psci_call(cpu, cs->exception_index)) {
arm_handle_psci_call(cpu);
qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
+ qemu_plugin_vcpu_hostcall_cb(cs, last_pc);
return;
}
@@ -9500,6 +9521,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
#ifdef CONFIG_TCG
if (cs->exception_index == EXCP_SEMIHOST) {
tcg_handle_semihosting(cs);
+ qemu_plugin_vcpu_hostcall_cb(cs, last_pc);
return;
}
#endif
@@ -9525,6 +9547,8 @@ void arm_cpu_do_interrupt(CPUState *cs)
if (!kvm_enabled()) {
cpu_set_interrupt(cs, CPU_INTERRUPT_EXITTB);
}
+
+ arm_do_plugin_vcpu_discon_cb(cs, last_pc);
}
#endif /* !CONFIG_USER_ONLY */
diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c
index d856e3bc8e2..3fb24c77900 100644
--- a/target/arm/tcg/m_helper.c
+++ b/target/arm/tcg/m_helper.c
@@ -23,6 +23,7 @@
#if !defined(CONFIG_USER_ONLY)
#include "hw/intc/armv7m_nvic.h"
#endif
+#include "qemu/plugin.h"
static void v7m_msr_xpsr(CPUARMState *env, uint32_t mask,
uint32_t reg, uint32_t val)
@@ -2194,6 +2195,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
CPUARMState *env = &cpu->env;
uint32_t lr;
bool ignore_stackfaults;
+ uint64_t last_pc = env->regs[15];
arm_log_exception(cs);
@@ -2361,6 +2363,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
g_assert_not_reached();
#endif
env->regs[15] += env->thumb ? 2 : 4;
+ qemu_plugin_vcpu_hostcall_cb(cs, last_pc);
return;
case EXCP_BKPT:
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG, false);
@@ -2427,6 +2430,8 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
ignore_stackfaults = v7m_push_stack(cpu);
v7m_exception_taken(cpu, lr, false, ignore_stackfaults);
+
+ arm_do_plugin_vcpu_discon_cb(cs, last_pc);
}
uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 13/35] target/avr: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (11 preceding siblings ...)
2025-10-29 15:50 ` [PULL 12/35] target/arm: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 14/35] target/hppa: " Alex Bennée
` (22 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Richard Henderson, Philippe Mathieu-Daudé,
Alex Bennée, Michael Rolnik
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places the hook for AVR targets. That architecture appears
to only know interrupts.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-14-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/avr/helper.c b/target/avr/helper.c
index 4b29ab35263..365c8c60e19 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -28,6 +28,7 @@
#include "exec/target_page.h"
#include "accel/tcg/cpu-ldst.h"
#include "exec/helper-proto.h"
+#include "qemu/plugin.h"
bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
@@ -102,6 +103,8 @@ void avr_cpu_do_interrupt(CPUState *cs)
env->sregI = 0; /* clear Global Interrupt Flag */
cs->exception_index = -1;
+
+ qemu_plugin_vcpu_interrupt_cb(cs, ret);
}
hwaddr avr_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 14/35] target/hppa: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (12 preceding siblings ...)
2025-10-29 15:50 ` [PULL 13/35] target/avr: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 15/35] target/i386: " Alex Bennée
` (21 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Philippe Mathieu-Daudé, Alex Bennée,
Richard Henderson, Helge Deller
From: Julian Ganz <neither@nut.email>
We identified a number of exceptions as interrupts, and we assume every
other exception is a (syncroneous) exceptions. PA-RISC appears to not
have any form of host-call.
This change places the hook for PA-RISC targets.
Signed-off-by: Julian Ganz <neither@nut.email>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-15-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 191ae19404b..4e4869285b5 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -24,6 +24,7 @@
#include "exec/helper-proto.h"
#include "hw/core/cpu.h"
#include "hw/hppa/hppa_hardware.h"
+#include "qemu/plugin.h"
static void eval_interrupt(HPPACPU *cpu)
{
@@ -95,6 +96,7 @@ void hppa_cpu_do_interrupt(CPUState *cs)
CPUHPPAState *env = &cpu->env;
int i = cs->exception_index;
uint64_t old_psw, old_gva_offset_mask;
+ uint64_t last_pc = cs->cc->get_pc(cs);
/* As documented in pa2.0 -- interruption handling. */
/* step 1 */
@@ -212,6 +214,21 @@ void hppa_cpu_do_interrupt(CPUState *cs)
env->iasq_f = 0;
env->iasq_b = 0;
+ switch (i) {
+ case EXCP_HPMC:
+ case EXCP_POWER_FAIL:
+ case EXCP_RC:
+ case EXCP_EXT_INTERRUPT:
+ case EXCP_LPMC:
+ case EXCP_PER_INTERRUPT:
+ case EXCP_TOC:
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
+ break;
+ default:
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
+ break;
+ }
+
if (qemu_loglevel_mask(CPU_LOG_INT)) {
static const char * const names[] = {
[EXCP_HPMC] = "high priority machine check",
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 15/35] target/i386: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (13 preceding siblings ...)
2025-10-29 15:50 ` [PULL 14/35] target/hppa: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 16/35] target/loongarch: " Alex Bennée
` (20 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Philippe Mathieu-Daudé, Alex Bennée,
Paolo Bonzini, Richard Henderson, Eduardo Habkost
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places the hook for x86 targets.
Signed-off-by: Julian Ganz <neither@nut.email>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-16-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/i386/tcg/excp_helper.c b/target/i386/tcg/excp_helper.c
index 6fb8036d988..32f2784e923 100644
--- a/target/i386/tcg/excp_helper.c
+++ b/target/i386/tcg/excp_helper.c
@@ -23,6 +23,7 @@
#include "system/runstate.h"
#include "exec/helper-proto.h"
#include "helper-tcg.h"
+#include "qemu/plugin.h"
G_NORETURN void helper_raise_interrupt(CPUX86State *env, int intno,
int next_eip_addend)
@@ -93,6 +94,7 @@ void raise_interrupt2(CPUX86State *env, int intno,
uintptr_t retaddr)
{
CPUState *cs = env_cpu(env);
+ uint64_t last_pc = env->eip + env->segs[R_CS].base;
if (!is_int) {
cpu_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno,
@@ -106,6 +108,7 @@ void raise_interrupt2(CPUX86State *env, int intno,
env->error_code = error_code;
env->exception_is_int = is_int;
env->exception_next_eip = env->eip + next_eip_addend;
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
cpu_loop_exit_restore(cs, retaddr);
}
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index f49fe851cdf..667b1c38696 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -29,6 +29,7 @@
#include "seg_helper.h"
#include "access.h"
#include "tcg-cpu.h"
+#include "qemu/plugin.h"
#ifdef TARGET_X86_64
#define SET_ESP(val, sp_mask) \
@@ -1192,6 +1193,7 @@ void do_interrupt_all(X86CPU *cpu, int intno, int is_int,
int error_code, target_ulong next_eip, int is_hw)
{
CPUX86State *env = &cpu->env;
+ uint64_t last_pc = env->eip + env->segs[R_CS].base;
if (qemu_loglevel_mask(CPU_LOG_INT)) {
if ((env->cr[0] & CR0_PE_MASK)) {
@@ -1263,6 +1265,8 @@ void do_interrupt_all(X86CPU *cpu, int intno, int is_int,
event_inj & ~SVM_EVTINJ_VALID);
}
#endif
+
+ qemu_plugin_vcpu_interrupt_cb(CPU(cpu), last_pc);
}
void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 16/35] target/loongarch: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (14 preceding siblings ...)
2025-10-29 15:50 ` [PULL 15/35] target/i386: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 17/35] target/m68k: " Alex Bennée
` (19 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Julian Ganz, Richard Henderson, Song Gao, Alex Bennée
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for loongarch targets. This architecture
has one special "exception" for interrupts and no host calls.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Reviewed-by: Song Gao <gaosong@loongson.cn>
Message-ID: <20251027110344.2289945-17-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/loongarch/tcg/tcg_cpu.c b/target/loongarch/tcg/tcg_cpu.c
index 82b54e6dc3c..9d077c56d9d 100644
--- a/target/loongarch/tcg/tcg_cpu.c
+++ b/target/loongarch/tcg/tcg_cpu.c
@@ -8,6 +8,7 @@
#include "qemu/accel.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
+#include "qemu/plugin.h"
#include "accel/accel-cpu-target.h"
#include "accel/tcg/cpu-ldst.h"
#include "accel/tcg/cpu-ops.h"
@@ -80,6 +81,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
int cause = -1;
bool tlbfill = FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR);
uint32_t vec_size = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, VS);
+ uint64_t last_pc = env->pc;
if (cs->exception_index != EXCCODE_INT) {
qemu_log_mask(CPU_LOG_INT,
@@ -190,6 +192,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
__func__, env->pc, env->CSR_ERA,
cause, env->CSR_BADV, env->CSR_DERA, vector,
env->CSR_ECFG, env->CSR_ESTAT);
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
} else {
if (tlbfill) {
set_pc(env, env->CSR_TLBRENTRY);
@@ -208,6 +211,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
tlbfill ? env->CSR_TLBRBADV : env->CSR_BADV,
env->CSR_BADI, env->gpr[11], cs->cpu_index,
env->CSR_ASID);
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
}
cs->exception_index = -1;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 17/35] target/m68k: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (15 preceding siblings ...)
2025-10-29 15:50 ` [PULL 16/35] target/loongarch: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 18/35] target/microblaze: " Alex Bennée
` (18 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Philippe Mathieu-Daudé, Alex Bennée,
Laurent Vivier
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for Motorola 68000 targets.
Signed-off-by: Julian Ganz <neither@nut.email>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-18-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index f29ae12af84..e9c20a8e032 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -22,6 +22,7 @@
#include "exec/helper-proto.h"
#include "accel/tcg/cpu-ldst.h"
#include "semihosting/semihost.h"
+#include "qemu/plugin.h"
#if !defined(CONFIG_USER_ONLY)
@@ -183,6 +184,21 @@ static const char *m68k_exception_name(int index)
return "Unassigned";
}
+static void do_plugin_vcpu_interrupt_cb(CPUState *cs, uint64_t from)
+{
+ switch (cs->exception_index) {
+ case EXCP_SPURIOUS ... EXCP_INT_LEVEL_7:
+ qemu_plugin_vcpu_interrupt_cb(cs, from);
+ break;
+ case EXCP_SEMIHOSTING:
+ qemu_plugin_vcpu_hostcall_cb(cs, from);
+ break;
+ default:
+ qemu_plugin_vcpu_exception_cb(cs, from);
+ break;
+ }
+}
+
static void cf_interrupt_all(CPUM68KState *env, int is_hw)
{
CPUState *cs = env_cpu(env);
@@ -203,6 +219,7 @@ static void cf_interrupt_all(CPUM68KState *env, int is_hw)
return;
case EXCP_SEMIHOSTING:
do_m68k_semihosting(env, env->dregs[0]);
+ qemu_plugin_vcpu_hostcall_cb(cs, retaddr);
return;
}
}
@@ -239,6 +256,8 @@ static void cf_interrupt_all(CPUM68KState *env, int is_hw)
env->aregs[7] = sp;
/* Jump to vector. */
env->pc = cpu_ldl_mmuidx_ra(env, env->vbr + vector, MMU_KERNEL_IDX, 0);
+
+ do_plugin_vcpu_interrupt_cb(cs, retaddr);
}
static inline void do_stack_frame(CPUM68KState *env, uint32_t *sp,
@@ -277,6 +296,7 @@ static void m68k_interrupt_all(CPUM68KState *env, int is_hw)
uint32_t sp;
uint32_t vector;
uint16_t sr, oldsr;
+ uint64_t last_pc = env->pc;
if (!is_hw) {
switch (cs->exception_index) {
@@ -417,6 +437,8 @@ static void m68k_interrupt_all(CPUM68KState *env, int is_hw)
env->aregs[7] = sp;
/* Jump to vector. */
env->pc = cpu_ldl_mmuidx_ra(env, env->vbr + vector, MMU_KERNEL_IDX, 0);
+
+ do_plugin_vcpu_interrupt_cb(cs, last_pc);
}
static void do_interrupt_all(CPUM68KState *env, int is_hw)
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 18/35] target/microblaze: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (16 preceding siblings ...)
2025-10-29 15:50 ` [PULL 17/35] target/m68k: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 19/35] target/mips: " Alex Bennée
` (17 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Philippe Mathieu-Daudé, Alex Bennée,
Edgar E. Iglesias
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places the hook for MicroBlaze targets. This architecture
has one special "exception" for interrupts and no host calls.
Signed-off-by: Julian Ganz <neither@nut.email>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-19-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index cf577a72268..a1857b72172 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -27,6 +27,7 @@
#include "qemu/host-utils.h"
#include "exec/log.h"
#include "exec/helper-proto.h"
+#include "qemu/plugin.h"
G_NORETURN
@@ -35,6 +36,7 @@ static void mb_unaligned_access_internal(CPUState *cs, uint64_t addr,
{
CPUMBState *env = cpu_env(cs);
uint32_t esr, iflags;
+ uint64_t last_pc = env->pc;
/* Recover the pc and iflags from the corresponding insn_start. */
cpu_restore_state(cs, retaddr);
@@ -54,6 +56,7 @@ static void mb_unaligned_access_internal(CPUState *cs, uint64_t addr,
env->ear = addr;
env->esr = esr;
cs->exception_index = EXCP_HW_EXCP;
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
cpu_loop_exit(cs);
}
@@ -152,6 +155,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
CPUMBState *env = &cpu->env;
uint32_t t, msr = mb_cpu_read_msr(env);
bool set_esr;
+ uint64_t last_pc = env->pc;
/* IMM flag cannot propagate across a branch and into the dslot. */
assert((env->iflags & (D_FLAG | IMM_FLAG)) != (D_FLAG | IMM_FLAG));
@@ -256,6 +260,12 @@ void mb_cpu_do_interrupt(CPUState *cs)
env->res_addr = RES_ADDR_NONE;
env->iflags = 0;
+ if (cs->exception_index == EXCP_IRQ) {
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
+ } else {
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
+ }
+
if (!set_esr) {
qemu_log_mask(CPU_LOG_INT,
" to pc=%08x msr=%08x\n", env->pc, msr);
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 19/35] target/mips: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (17 preceding siblings ...)
2025-10-29 15:50 ` [PULL 18/35] target/microblaze: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 20/35] target/openrisc: " Alex Bennée
` (16 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Richard Henderson, Philippe Mathieu-Daudé,
Alex Bennée, Aurelien Jarno, Jiaxun Yang, Aleksandar Rikalo
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for MIPS targets. We consider the exceptions
NMI and EXT_INTERRUPT to be asynchronous interrupts rather than
exceptions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-20-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/mips/tcg/system/tlb_helper.c b/target/mips/tcg/system/tlb_helper.c
index 1e8901556d6..566924b079e 100644
--- a/target/mips/tcg/system/tlb_helper.c
+++ b/target/mips/tcg/system/tlb_helper.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/bitops.h"
+#include "qemu/plugin.h"
#include "cpu.h"
#include "internal.h"
@@ -1034,6 +1035,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
bool update_badinstr = 0;
target_ulong offset;
int cause = -1;
+ uint64_t last_pc = env->active_tc.PC;
if (qemu_loglevel_mask(CPU_LOG_INT)
&& cs->exception_index != EXCP_EXT_INTERRUPT) {
@@ -1052,6 +1054,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
cs->exception_index = EXCP_NONE;
mips_semihosting(env);
env->active_tc.PC += env->error_code;
+ qemu_plugin_vcpu_hostcall_cb(cs, last_pc);
return;
case EXCP_DSS:
env->CP0_Debug |= 1 << CP0DB_DSS;
@@ -1336,6 +1339,14 @@ void mips_cpu_do_interrupt(CPUState *cs)
env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr,
env->CP0_DEPC);
}
+ switch (cs->exception_index) {
+ case EXCP_NMI:
+ case EXCP_EXT_INTERRUPT:
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
+ break;
+ default:
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
+ }
cs->exception_index = EXCP_NONE;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 20/35] target/openrisc: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (18 preceding siblings ...)
2025-10-29 15:50 ` [PULL 19/35] target/mips: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 21/35] target/ppc: " Alex Bennée
` (15 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Philippe Mathieu-Daudé, Alex Bennée,
Stafford Horne
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for OpenRISC targets. We treat anything other
than resets, timer and device interrupts as exceptions.
Signed-off-by: Julian Ganz <neither@nut.email>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-21-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index 486823094c8..d357aaa7da1 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -25,11 +25,13 @@
#ifndef CONFIG_USER_ONLY
#include "hw/loader.h"
#endif
+#include "qemu/plugin.h"
void openrisc_cpu_do_interrupt(CPUState *cs)
{
CPUOpenRISCState *env = cpu_env(cs);
int exception = cs->exception_index;
+ uint64_t last_pc = env->pc;
env->epcr = env->pc;
@@ -98,6 +100,19 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
cpu_abort(cs, "Unhandled exception 0x%x\n", exception);
}
+ switch (exception) {
+ case EXCP_RESET:
+ /* Resets are already exposed to plugins through a dedicated callback */
+ break;
+ case EXCP_TICK:
+ case EXCP_INT:
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
+ break;
+ default:
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
+ break;
+ }
+
cs->exception_index = -1;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 21/35] target/ppc: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (19 preceding siblings ...)
2025-10-29 15:50 ` [PULL 20/35] target/openrisc: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 22/35] target/riscv: " Alex Bennée
` (14 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Alex Bennée, Nicholas Piggin, Chinmay Rath,
open list:PowerPC TCG CPUs
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for Power PC targets.
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-22-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index d8bca19fff5..6d05b865058 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -27,6 +27,7 @@
#include "internal.h"
#include "helper_regs.h"
#include "hw/ppc/ppc.h"
+#include "qemu/plugin.h"
#include "trace.h"
@@ -404,11 +405,31 @@ static void powerpc_mcheck_checkstop(CPUPPCState *env)
powerpc_checkstop(env, "machine check with MSR[ME]=0");
}
+static void powerpc_do_plugin_vcpu_interrupt_cb(CPUState *cs, int excp,
+ uint64_t from)
+{
+ switch (excp) {
+ case POWERPC_EXCP_NONE:
+ break;
+ case POWERPC_EXCP_FIT:
+ case POWERPC_EXCP_WDT:
+ case POWERPC_EXCP_PIT:
+ case POWERPC_EXCP_SMI:
+ case POWERPC_EXCP_PERFM:
+ case POWERPC_EXCP_THERM:
+ qemu_plugin_vcpu_interrupt_cb(cs, from);
+ break;
+ default:
+ qemu_plugin_vcpu_exception_cb(cs, from);
+ }
+}
+
static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
{
CPUPPCState *env = &cpu->env;
target_ulong msr, new_msr, vector;
int srr0 = SPR_SRR0, srr1 = SPR_SRR1;
+ uint64_t last_pc = env->nip;
/* new srr1 value excluding must-be-zero bits */
msr = env->msr & ~0x783f0000ULL;
@@ -456,6 +477,7 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
trace_ppc_excp_fp_ignore();
powerpc_reset_excp_state(cpu);
+ qemu_plugin_vcpu_exception_cb(env_cpu(env), last_pc);
return;
}
env->spr[SPR_40x_ESR] = ESR_FP;
@@ -510,12 +532,14 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
env->spr[srr0] = env->nip;
env->spr[srr1] = msr;
powerpc_set_excp_state(cpu, vector, new_msr);
+ powerpc_do_plugin_vcpu_interrupt_cb(env_cpu(env), excp, last_pc);
}
static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
{
CPUPPCState *env = &cpu->env;
target_ulong msr, new_msr, vector;
+ uint64_t last_pc = env->nip;
/* new srr1 value excluding must-be-zero bits */
msr = env->msr & ~0x783f0000ULL;
@@ -567,6 +591,7 @@ static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
trace_ppc_excp_fp_ignore();
powerpc_reset_excp_state(cpu);
+ qemu_plugin_vcpu_exception_cb(env_cpu(env), last_pc);
return;
}
/*
@@ -653,12 +678,14 @@ static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
env->spr[SPR_SRR0] = env->nip;
env->spr[SPR_SRR1] = msr;
powerpc_set_excp_state(cpu, vector, new_msr);
+ powerpc_do_plugin_vcpu_interrupt_cb(env_cpu(env), excp, last_pc);
}
static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
{
CPUPPCState *env = &cpu->env;
target_ulong msr, new_msr, vector;
+ uint64_t last_pc = env->nip;
/* new srr1 value excluding must-be-zero bits */
msr = env->msr & ~0x783f0000ULL;
@@ -708,6 +735,7 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
trace_ppc_excp_fp_ignore();
powerpc_reset_excp_state(cpu);
+ qemu_plugin_vcpu_exception_cb(env_cpu(env), last_pc);
return;
}
/*
@@ -758,6 +786,7 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
if (lev == 1 && cpu->vhyp) {
cpu->vhyp_class->hypercall(cpu->vhyp, cpu);
powerpc_reset_excp_state(cpu);
+ qemu_plugin_vcpu_hostcall_cb(env_cpu(env), last_pc);
return;
}
@@ -803,12 +832,14 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
env->spr[SPR_SRR0] = env->nip;
env->spr[SPR_SRR1] = msr;
powerpc_set_excp_state(cpu, vector, new_msr);
+ powerpc_do_plugin_vcpu_interrupt_cb(env_cpu(env), excp, last_pc);
}
static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
{
CPUPPCState *env = &cpu->env;
target_ulong msr, new_msr, vector;
+ uint64_t last_pc = env->nip;
/* new srr1 value excluding must-be-zero bits */
msr = env->msr & ~0x783f0000ULL;
@@ -858,6 +889,7 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
trace_ppc_excp_fp_ignore();
powerpc_reset_excp_state(cpu);
+ qemu_plugin_vcpu_exception_cb(env_cpu(env), last_pc);
return;
}
/*
@@ -908,6 +940,7 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
if (lev == 1 && cpu->vhyp) {
cpu->vhyp_class->hypercall(cpu->vhyp, cpu);
powerpc_reset_excp_state(cpu);
+ qemu_plugin_vcpu_hostcall_cb(env_cpu(env), last_pc);
return;
}
@@ -947,6 +980,7 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
env->spr[SPR_SRR0] = env->nip;
env->spr[SPR_SRR1] = msr;
powerpc_set_excp_state(cpu, vector, new_msr);
+ powerpc_do_plugin_vcpu_interrupt_cb(env_cpu(env), excp, last_pc);
}
static void powerpc_excp_ppe42(PowerPCCPU *cpu, int excp)
@@ -1073,6 +1107,7 @@ static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
CPUPPCState *env = &cpu->env;
target_ulong msr, new_msr, vector;
int srr0 = SPR_SRR0, srr1 = SPR_SRR1;
+ uint64_t last_pc = env->nip;
/*
* Book E does not play games with certain bits of xSRR1 being MSR save
@@ -1144,6 +1179,7 @@ static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
trace_ppc_excp_fp_ignore();
powerpc_reset_excp_state(cpu);
+ qemu_plugin_vcpu_exception_cb(env_cpu(env), last_pc);
return;
}
/*
@@ -1252,6 +1288,7 @@ static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
env->spr[srr0] = env->nip;
env->spr[srr1] = msr;
powerpc_set_excp_state(cpu, vector, new_msr);
+ powerpc_do_plugin_vcpu_interrupt_cb(env_cpu(env), excp, last_pc);
}
/*
@@ -1373,6 +1410,7 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
CPUPPCState *env = &cpu->env;
target_ulong msr, new_msr, vector;
int srr0 = SPR_SRR0, srr1 = SPR_SRR1, lev = -1;
+ uint64_t last_pc = env->nip;
/* new srr1 value excluding must-be-zero bits */
msr = env->msr & ~0x783f0000ULL;
@@ -1472,6 +1510,7 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
trace_ppc_excp_fp_ignore();
powerpc_reset_excp_state(cpu);
+ qemu_plugin_vcpu_exception_cb(env_cpu(env), last_pc);
return;
}
/*
@@ -1516,6 +1555,7 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
if (lev == 1 && books_vhyp_handles_hcall(cpu)) {
cpu->vhyp_class->hypercall(cpu->vhyp, cpu);
powerpc_reset_excp_state(cpu);
+ qemu_plugin_vcpu_hostcall_cb(env_cpu(env), last_pc);
return;
}
if (env->insns_flags2 & PPC2_ISA310) {
@@ -1662,6 +1702,7 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
ppc_excp_apply_ail(cpu, excp, msr, &new_msr, &vector);
powerpc_set_excp_state(cpu, vector, new_msr);
}
+ powerpc_do_plugin_vcpu_interrupt_cb(env_cpu(env), excp, last_pc);
}
#else
static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp)
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 22/35] target/riscv: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (20 preceding siblings ...)
2025-10-29 15:50 ` [PULL 21/35] target/ppc: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 23/35] target/rx: " Alex Bennée
` (13 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Daniel Henrique Barboza, Alistair Francis,
Alex Bennée, Palmer Dabbelt, Weiwei Li, Liu Zhiwei,
open list:RISC-V TCG CPUs
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for RISC-V targets.
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-23-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 360db133e21..c4fb68b5de8 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -36,6 +36,7 @@
#include "cpu_bits.h"
#include "debug.h"
#include "pmp.h"
+#include "qemu/plugin.h"
int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
{
@@ -2175,6 +2176,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
uint64_t hdeleg = async ? env->hideleg : env->hedeleg;
const bool prev_virt = env->virt_enabled;
const target_ulong prev_priv = env->priv;
+ uint64_t last_pc = env->pc;
target_ulong tval = 0;
target_ulong tinst = 0;
target_ulong htval = 0;
@@ -2197,6 +2199,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
case RISCV_EXCP_SEMIHOST:
do_common_semihosting(cs);
env->pc += 4;
+ qemu_plugin_vcpu_hostcall_cb(cs, last_pc);
return;
#endif
case RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT:
@@ -2466,6 +2469,12 @@ void riscv_cpu_do_interrupt(CPUState *cs)
prev_priv, prev_virt);
}
+ if (async) {
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
+ } else {
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
+ }
+
/*
* Interrupt/exception/trap delivery is asynchronous event and as per
* zicfilp spec CPU should clear up the ELP state. No harm in clearing
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 23/35] target/rx: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (21 preceding siblings ...)
2025-10-29 15:50 ` [PULL 22/35] target/riscv: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 24/35] target/s390x: " Alex Bennée
` (12 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Richard Henderson, Yoshinori Sato,
Philippe Mathieu-Daudé, Alex Bennée
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for Renesas Xtreme targets.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Yoshinori Sato <yoshinori.sato@nifty.com>
Signed-off-by: Julian Ganz <neither@nut.email>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-24-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/rx/helper.c b/target/rx/helper.c
index 41c9606fd1d..ef47e32add8 100644
--- a/target/rx/helper.c
+++ b/target/rx/helper.c
@@ -22,6 +22,7 @@
#include "exec/log.h"
#include "accel/tcg/cpu-ldst.h"
#include "hw/irq.h"
+#include "qemu/plugin.h"
void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte)
{
@@ -46,6 +47,7 @@ void rx_cpu_do_interrupt(CPUState *cs)
CPURXState *env = cpu_env(cs);
int do_irq = cpu_test_interrupt(cs, INT_FLAGS);
uint32_t save_psw;
+ uint64_t last_pc = env->pc;
env->in_sleep = 0;
@@ -65,6 +67,7 @@ void rx_cpu_do_interrupt(CPUState *cs)
env->psw_ipl = 15;
cpu_reset_interrupt(cs, CPU_INTERRUPT_FIR);
qemu_set_irq(env->ack, env->ack_irq);
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
qemu_log_mask(CPU_LOG_INT, "fast interrupt raised\n");
} else if (do_irq & CPU_INTERRUPT_HARD) {
env->isp -= 4;
@@ -75,6 +78,7 @@ void rx_cpu_do_interrupt(CPUState *cs)
env->psw_ipl = env->ack_ipl;
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
qemu_set_irq(env->ack, env->ack_irq);
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
qemu_log_mask(CPU_LOG_INT,
"interrupt 0x%02x raised\n", env->ack_irq);
}
@@ -92,6 +96,14 @@ void rx_cpu_do_interrupt(CPUState *cs)
} else {
env->pc = cpu_ldl_data(env, env->intb + (vec & 0xff) * 4);
}
+
+ if (vec == 30) {
+ /* Non-maskable interrupt */
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
+ } else {
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
+ }
+
switch (vec) {
case 20:
expname = "privilege violation";
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 24/35] target/s390x: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (22 preceding siblings ...)
2025-10-29 15:50 ` [PULL 23/35] target/rx: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 25/35] target/sh4: " Alex Bennée
` (11 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, David Hildenbrand, Richard Henderson,
Alex Bennée, Ilya Leoshkevich, Thomas Huth,
open list:S390 TCG CPUs
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for IBM System/390 targets. We treat "program
interrupts" and service calls as exceptions. We treat external and io
"exceptions" as well as resets as interrupts.
Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-25-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c
index 0ae4e266065..c6641280bc6 100644
--- a/target/s390x/tcg/excp_helper.c
+++ b/target/s390x/tcg/excp_helper.c
@@ -35,6 +35,7 @@
#include "hw/s390x/s390_flic.h"
#include "hw/boards.h"
#endif
+#include "qemu/plugin.h"
G_NORETURN void tcg_s390_program_interrupt(CPUS390XState *env,
uint32_t code, uintptr_t ra)
@@ -502,6 +503,7 @@ void s390_cpu_do_interrupt(CPUState *cs)
S390CPU *cpu = S390_CPU(cs);
CPUS390XState *env = &cpu->env;
bool stopped = false;
+ uint64_t last_pc = cpu->env.psw.addr;
qemu_log_mask(CPU_LOG_INT, "%s: %d at psw=%" PRIx64 ":%" PRIx64 "\n",
__func__, cs->exception_index, env->psw.mask, env->psw.addr);
@@ -531,21 +533,27 @@ try_deliver:
switch (cs->exception_index) {
case EXCP_PGM:
do_program_interrupt(env);
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
break;
case EXCP_SVC:
do_svc_interrupt(env);
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
break;
case EXCP_EXT:
do_ext_interrupt(env);
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
break;
case EXCP_IO:
do_io_interrupt(env);
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
break;
case EXCP_MCHK:
do_mchk_interrupt(env);
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
break;
case EXCP_RESTART:
do_restart_interrupt(env);
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
break;
case EXCP_STOP:
do_stop_interrupt(env);
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 25/35] target/sh4: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (23 preceding siblings ...)
2025-10-29 15:50 ` [PULL 24/35] target/s390x: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 26/35] target/sparc: " Alex Bennée
` (10 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Richard Henderson, Yoshinori Sato, Alex Bennée
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for SuperH targets.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Yoshinori Sato <yoshinori.sato@nifty.com>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-26-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 3b18a320b86..5d6295618f5 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -24,6 +24,7 @@
#include "exec/page-protection.h"
#include "exec/target_page.h"
#include "exec/log.h"
+#include "qemu/plugin.h"
#if !defined(CONFIG_USER_ONLY)
#include "hw/sh4/sh_intc.h"
@@ -60,6 +61,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
CPUSH4State *env = cpu_env(cs);
int do_irq = cpu_test_interrupt(cs, CPU_INTERRUPT_HARD);
int do_exp, irq_vector = cs->exception_index;
+ uint64_t last_pc = env->pc;
/* prioritize exceptions over interrupts */
@@ -176,12 +178,14 @@ void superh_cpu_do_interrupt(CPUState *cs)
env->pc = env->vbr + 0x100;
break;
}
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
return;
}
if (do_irq) {
env->intevt = irq_vector;
env->pc = env->vbr + 0x600;
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
return;
}
}
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 26/35] target/sparc: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (24 preceding siblings ...)
2025-10-29 15:50 ` [PULL 25/35] target/sh4: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 27/35] target/tricore: " Alex Bennée
` (9 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Richard Henderson, Philippe Mathieu-Daudé,
Alex Bennée, Mark Cave-Ayland, Artyom Tarasenko
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for SPARC (32bit and 64bit) targets. We treat
any interrupt other than EXTINT and IVEC as exceptions as they appear to
be synchroneous events.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-27-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c
index fdcaa0a578b..b29f693a6bf 100644
--- a/target/sparc/int32_helper.c
+++ b/target/sparc/int32_helper.c
@@ -24,6 +24,7 @@
#include "accel/tcg/cpu-ldst.h"
#include "exec/log.h"
#include "system/runstate.h"
+#include "qemu/plugin.h"
static const char * const excp_names[0x80] = {
[TT_TFAULT] = "Instruction Access Fault",
@@ -174,4 +175,10 @@ void sparc_cpu_do_interrupt(CPUState *cs)
env->qemu_irq_ack(env, intno);
}
#endif
+
+ if (intno == TT_EXTINT) {
+ qemu_plugin_vcpu_interrupt_cb(cs, env->regwptr[9]);
+ } else {
+ qemu_plugin_vcpu_exception_cb(cs, env->regwptr[9]);
+ }
}
diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c
index 96ef81c26cd..60ab0478fc6 100644
--- a/target/sparc/int64_helper.c
+++ b/target/sparc/int64_helper.c
@@ -24,6 +24,7 @@
#include "exec/helper-proto.h"
#include "exec/log.h"
#include "trace.h"
+#include "qemu/plugin.h"
#define DEBUG_PCALL
@@ -256,6 +257,15 @@ void sparc_cpu_do_interrupt(CPUState *cs)
}
env->npc = env->pc + 4;
cs->exception_index = -1;
+
+ switch (intno) {
+ case TT_EXTINT:
+ case TT_IVEC:
+ qemu_plugin_vcpu_interrupt_cb(cs, tsptr->tpc);
+ break;
+ default:
+ qemu_plugin_vcpu_exception_cb(cs, tsptr->tpc);
+ }
}
trap_state *cpu_tsptr(CPUSPARCState* env)
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 27/35] target/tricore: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (25 preceding siblings ...)
2025-10-29 15:50 ` [PULL 26/35] target/sparc: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 28/35] target/xtensa: " Alex Bennée
` (8 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Bastian Koppelmann, Richard Henderson,
Alex Bennée
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places an exception hook for TriCore targets. Interrupts are
not implemented for this target and it has no host calls.
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-28-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c
index 610f148a237..2c8281a67e0 100644
--- a/target/tricore/op_helper.c
+++ b/target/tricore/op_helper.c
@@ -19,6 +19,7 @@
#include "qemu/host-utils.h"
#include "exec/helper-proto.h"
#include "accel/tcg/cpu-ldst.h"
+#include "qemu/plugin.h"
#include <zlib.h> /* for crc32 */
@@ -29,8 +30,11 @@ void raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin
uintptr_t pc, uint32_t fcd_pc)
{
CPUState *cs = env_cpu(env);
+ uint64_t last_pc;
+
/* in case we come from a helper-call we need to restore the PC */
cpu_restore_state(cs, pc);
+ last_pc = env->PC;
/* Tin is loaded into d[15] */
env->gpr_d[15] = tin;
@@ -90,6 +94,7 @@ void raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin
/* Update PC using the trap vector table */
env->PC = env->BTV | (class << 5);
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
cpu_loop_exit(cs);
}
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 28/35] target/xtensa: call plugin trap callbacks
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (26 preceding siblings ...)
2025-10-29 15:50 ` [PULL 27/35] target/tricore: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 29/35] tests: add plugin asserting correctness of discon event's to_pc Alex Bennée
` (7 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Max Filippov, Philippe Mathieu-Daudé,
Alex Bennée
From: Julian Ganz <neither@nut.email>
We recently introduced API for registering callbacks for trap related
events as well as the corresponding hook functions. Due to differences
between architectures, the latter need to be called from target specific
code.
This change places hooks for xtensa targets.
Reviewed-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-29-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
index b611c9bf97c..fdc522698dc 100644
--- a/target/xtensa/exc_helper.c
+++ b/target/xtensa/exc_helper.c
@@ -32,6 +32,7 @@
#include "exec/helper-proto.h"
#include "qemu/host-utils.h"
#include "qemu/atomic.h"
+#include "qemu/plugin.h"
void HELPER(exception)(CPUXtensaState *env, uint32_t excp)
{
@@ -207,6 +208,8 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
CPUXtensaState *env = cpu_env(cs);
if (cs->exception_index == EXC_IRQ) {
+ uint64_t last_pc = env->pc;
+
qemu_log_mask(CPU_LOG_INT,
"%s(EXC_IRQ) level = %d, cintlevel = %d, "
"pc = %08x, a0 = %08x, ps = %08x, "
@@ -218,6 +221,7 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
env->sregs[INTSET], env->sregs[INTENABLE],
env->sregs[CCOUNT]);
handle_interrupt(env);
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc);
}
switch (cs->exception_index) {
@@ -238,9 +242,11 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
env->sregs[CCOUNT]);
if (env->config->exception_vector[cs->exception_index]) {
uint32_t vector;
+ uint64_t last_pc = env->pc;
vector = env->config->exception_vector[cs->exception_index];
env->pc = relocated_vector(env, vector);
+ qemu_plugin_vcpu_exception_cb(cs, last_pc);
} else {
qemu_log_mask(CPU_LOG_INT,
"%s(pc = %08x) bad exception_index: %d\n",
diff --git a/target/xtensa/xtensa-semi.c b/target/xtensa/xtensa-semi.c
index 552815ebfdb..28dfb29cbd3 100644
--- a/target/xtensa/xtensa-semi.c
+++ b/target/xtensa/xtensa-semi.c
@@ -35,6 +35,7 @@
#include "system/memory.h"
#include "qapi/error.h"
#include "qemu/log.h"
+#include "qemu/plugin.h"
enum {
TARGET_SYS_exit = 1,
@@ -197,6 +198,7 @@ void HELPER(simcall)(CPUXtensaState *env)
CPUState *cs = env_cpu(env);
AddressSpace *as = cs->as;
uint32_t *regs = env->regs;
+ uint64_t last_pc = env->pc;
switch (regs[2]) {
case TARGET_SYS_exit:
@@ -433,4 +435,5 @@ void HELPER(simcall)(CPUXtensaState *env)
regs[3] = TARGET_ENOSYS;
break;
}
+ qemu_plugin_vcpu_hostcall_cb(cs, last_pc);
}
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 29/35] tests: add plugin asserting correctness of discon event's to_pc
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (27 preceding siblings ...)
2025-10-29 15:50 ` [PULL 28/35] target/xtensa: " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 30/35] tests: add test for double-traps on rv64 Alex Bennée
` (6 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Pierrick Bouvier, Alex Bennée, Alexandre Iooss,
Mahmoud Mandour
From: Julian Ganz <neither@nut.email>
We recently introduced plugin API for the registration of callbacks for
discontinuity events, specifically for interrupts, exceptions and host
call events. The callback receives various bits of information,
including the VCPU index and PCs.
This change introduces a test plugin asserting the correctness of that
behaviour in cases where this is possible with reasonable effort.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-30-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/tests/tcg/plugins/discons.c b/tests/tcg/plugins/discons.c
new file mode 100644
index 00000000000..2e0e664e823
--- /dev/null
+++ b/tests/tcg/plugins/discons.c
@@ -0,0 +1,221 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2025, Julian Ganz <neither@nut.email>
+ *
+ * This plugin exercises the discontinuity plugin API and asserts some
+ * of its behaviour regarding reported program counters.
+ */
+#include <stdio.h>
+
+#include <qemu-plugin.h>
+
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
+struct cpu_state {
+ uint64_t last_pc;
+ uint64_t from_pc;
+ uint64_t next_pc;
+ uint64_t has_from;
+ bool has_next;
+ enum qemu_plugin_discon_type next_type;
+};
+
+struct insn_data {
+ uint64_t addr;
+ uint64_t next_pc;
+ bool next_valid;
+};
+
+static struct qemu_plugin_scoreboard *states;
+
+static qemu_plugin_u64 last_pc;
+static qemu_plugin_u64 from_pc;
+static qemu_plugin_u64 has_from;
+
+static bool abort_on_mismatch;
+static bool trace_all_insns;
+
+static bool addr_eq(uint64_t a, uint64_t b)
+{
+ if (a == b) {
+ return true;
+ }
+
+ uint64_t a_hw;
+ uint64_t b_hw;
+ if (!qemu_plugin_translate_vaddr(a, &a_hw) ||
+ !qemu_plugin_translate_vaddr(b, &b_hw))
+ {
+ return false;
+ }
+
+ return a_hw == b_hw;
+}
+
+static void report_mismatch(const char *pc_name, unsigned int vcpu_index,
+ enum qemu_plugin_discon_type type, uint64_t last,
+ uint64_t expected, uint64_t encountered)
+{
+ gchar *report;
+ const char *discon_type_name = "unknown";
+
+ if (addr_eq(expected, encountered)) {
+ return;
+ }
+
+ switch (type) {
+ case QEMU_PLUGIN_DISCON_INTERRUPT:
+ discon_type_name = "interrupt";
+ break;
+ case QEMU_PLUGIN_DISCON_EXCEPTION:
+ discon_type_name = "exception";
+ break;
+ case QEMU_PLUGIN_DISCON_HOSTCALL:
+ discon_type_name = "hostcall";
+ break;
+ default:
+ break;
+ }
+
+ report = g_strdup_printf("Discon %s PC mismatch on VCPU %d\n"
+ "Expected: %"PRIx64"\nEncountered: %"
+ PRIx64"\nExecuted Last: %"PRIx64
+ "\nEvent type: %s\n",
+ pc_name, vcpu_index, expected, encountered, last,
+ discon_type_name);
+ if (abort_on_mismatch) {
+ /*
+ * The qemu log infrastructure may lose messages when aborting. Using
+ * fputs directly ensures the final report is visible to developers.
+ */
+ fputs(report, stderr);
+ g_abort();
+ } else {
+ qemu_plugin_outs(report);
+ }
+ g_free(report);
+}
+
+static void vcpu_discon(qemu_plugin_id_t id, unsigned int vcpu_index,
+ enum qemu_plugin_discon_type type, uint64_t from_pc,
+ uint64_t to_pc)
+{
+ struct cpu_state *state = qemu_plugin_scoreboard_find(states, vcpu_index);
+
+ if (type == QEMU_PLUGIN_DISCON_EXCEPTION &&
+ addr_eq(state->last_pc, from_pc))
+ {
+ /*
+ * For some types of exceptions, insn_exec will be called for the
+ * instruction that caused the exception. This is valid behaviour and
+ * does not need to be reported.
+ */
+ } else if (state->has_next) {
+ /*
+ * We may encounter discontinuity chains without any instructions
+ * being executed in between.
+ */
+ report_mismatch("source", vcpu_index, type, state->last_pc,
+ state->next_pc, from_pc);
+ } else if (state->has_from) {
+ report_mismatch("source", vcpu_index, type, state->last_pc,
+ state->from_pc, from_pc);
+ }
+
+ state->has_from = false;
+
+ state->next_pc = to_pc;
+ state->next_type = type;
+ state->has_next = true;
+}
+
+static void insn_exec(unsigned int vcpu_index, void *userdata)
+{
+ struct cpu_state *state = qemu_plugin_scoreboard_find(states, vcpu_index);
+
+ if (state->has_next) {
+ report_mismatch("target", vcpu_index, state->next_type, state->last_pc,
+ state->next_pc, state->last_pc);
+ state->has_next = false;
+ }
+
+ if (trace_all_insns) {
+ g_autoptr(GString) report = g_string_new(NULL);
+ g_string_append_printf(report, "Exec insn at %"PRIx64" on VCPU %d\n",
+ state->last_pc, vcpu_index);
+ qemu_plugin_outs(report->str);
+ }
+}
+
+static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
+{
+ size_t n_insns = qemu_plugin_tb_n_insns(tb);
+ for (size_t i = 0; i < n_insns; i++) {
+ struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i);
+ uint64_t pc = qemu_plugin_insn_vaddr(insn);
+ uint64_t next_pc = pc + qemu_plugin_insn_size(insn);
+ uint64_t has_next = (i + 1) < n_insns;
+
+ qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu(insn,
+ QEMU_PLUGIN_INLINE_STORE_U64,
+ last_pc, pc);
+ qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu(insn,
+ QEMU_PLUGIN_INLINE_STORE_U64,
+ from_pc, next_pc);
+ qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu(insn,
+ QEMU_PLUGIN_INLINE_STORE_U64,
+ has_from, has_next);
+ qemu_plugin_register_vcpu_insn_exec_cb(insn, insn_exec,
+ QEMU_PLUGIN_CB_NO_REGS, NULL);
+ }
+}
+
+QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
+ const qemu_info_t *info,
+ int argc, char **argv)
+{
+ if (!info->system_emulation) {
+ qemu_plugin_outs("Testing of the disontinuity plugin API is only"
+ " possible in system emulation mode.");
+ return 0;
+ }
+
+ /* Set defaults */
+ abort_on_mismatch = true;
+ trace_all_insns = false;
+
+ for (int i = 0; i < argc; i++) {
+ char *opt = argv[i];
+ g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);
+ if (g_strcmp0(tokens[0], "abort") == 0) {
+ if (!qemu_plugin_bool_parse(tokens[0], tokens[1],
+ &abort_on_mismatch)) {
+ fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
+ return -1;
+ }
+ } else if (g_strcmp0(tokens[0], "trace-all") == 0) {
+ if (!qemu_plugin_bool_parse(tokens[0], tokens[1],
+ &trace_all_insns)) {
+ fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "option parsing failed: %s\n", opt);
+ return -1;
+ }
+ }
+
+ states = qemu_plugin_scoreboard_new(sizeof(struct cpu_state));
+ last_pc = qemu_plugin_scoreboard_u64_in_struct(states, struct cpu_state,
+ last_pc);
+ from_pc = qemu_plugin_scoreboard_u64_in_struct(states, struct cpu_state,
+ from_pc);
+ has_from = qemu_plugin_scoreboard_u64_in_struct(states, struct cpu_state,
+ has_from);
+
+ qemu_plugin_register_vcpu_discon_cb(id, QEMU_PLUGIN_DISCON_ALL,
+ vcpu_discon);
+ qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
+
+ return 0;
+}
diff --git a/tests/tcg/plugins/meson.build b/tests/tcg/plugins/meson.build
index 61a007d9e74..561584159eb 100644
--- a/tests/tcg/plugins/meson.build
+++ b/tests/tcg/plugins/meson.build
@@ -1,6 +1,6 @@
t = []
if get_option('plugins')
- foreach i : ['bb', 'empty', 'inline', 'insn', 'mem', 'reset', 'syscall', 'patch']
+ foreach i : ['bb', 'discons', 'empty', 'inline', 'insn', 'mem', 'reset', 'syscall', 'patch']
if host_os == 'windows'
t += shared_module(i, files(i + '.c') + '../../../contrib/plugins/win32_linker.c',
include_directories: '../../../include/qemu',
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 30/35] tests: add test for double-traps on rv64
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (28 preceding siblings ...)
2025-10-29 15:50 ` [PULL 29/35] tests: add plugin asserting correctness of discon event's to_pc Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 31/35] tests: add test with interrupted memory accesses " Alex Bennée
` (5 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Daniel Henrique Barboza, Alistair Francis,
Alex Bennée, Palmer Dabbelt, Weiwei Li, Liu Zhiwei,
open list:RISC-V TCG CPUs
From: Julian Ganz <neither@nut.email>
We do have a number of test-case for various architectures exercising
their interrupt/exception logic. However, for the recently introduced
trap API we also want to exercise the logic for double traps on at least
one architecture.
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-31-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/tests/tcg/riscv64/Makefile.softmmu-target b/tests/tcg/riscv64/Makefile.softmmu-target
index 3ca595335dd..d9c0036eb4b 100644
--- a/tests/tcg/riscv64/Makefile.softmmu-target
+++ b/tests/tcg/riscv64/Makefile.softmmu-target
@@ -24,5 +24,11 @@ EXTRA_RUNS += run-test-mepc-masking
run-test-mepc-masking: test-mepc-masking
$(call run-test, $<, $(QEMU) $(QEMU_OPTS)$<)
+EXTRA_RUNS += run-plugin-doubletrap
+run-plugin-doubletrap: doubletrap
+ $(call run-test, $<, \
+ $(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $<.pout \
+ $(QEMU_OPTS)$<)
+
# We don't currently support the multiarch system tests
undefine MULTIARCH_TESTS
diff --git a/tests/tcg/riscv64/doubletrap.S b/tests/tcg/riscv64/doubletrap.S
new file mode 100644
index 00000000000..b61089c9c1c
--- /dev/null
+++ b/tests/tcg/riscv64/doubletrap.S
@@ -0,0 +1,73 @@
+ .option norvc
+
+ .text
+ .global _start
+_start:
+ # Set up vectored interrupts
+ lla t0, trap
+ add t0, t0, 1
+ csrw mtvec, t0
+
+ # Enable sw interrupts
+ csrrsi zero, mie, 0x8
+ csrrsi zero, mstatus, 0x8
+
+ # Engage the double trap: we trigger an machine-level software
+ # interrupt, which will trap to an illegal instruction
+ lui t1, 0x02000
+ li t0, 1
+ sw t0, 0(t1)
+
+ # If we still not went out via the software interrupt route after a
+ # short while, we failed the test.
+ lui t0, 0x1
+0:
+ addi t0, t0, -1
+ bnez t0, 0b
+ j fail
+
+trap:
+ j illegal_insn # Exceptions
+ j fail # Supervisor software interrupt
+ j fail
+ .insn i CUSTOM_0, 0, x0, x0, 0 # Machine software interrupt
+ j fail
+ j fail # Supervisor timer interrupt
+ j fail
+ j fail # Machine timer interrupt
+ j fail
+ j fail # Supervisor external interrupt
+ j fail
+ j fail # Machine external interrupt
+ j fail
+ j fail # Counter overflow interrupt
+ j fail
+ j fail
+
+illegal_insn:
+ # Check whether we really got an illegal instruction
+ csrr t0, mcause
+ li t1, 2
+ bne t0, t1, fail
+ li a0, 0
+ j _exit
+fail:
+ li a0, 1
+_exit:
+ lla a1, semiargs
+ li t0, 0x20026 # ADP_Stopped_ApplicationExit
+ sd t0, 0(a1)
+ sd a0, 8(a1)
+ li a0, 0x20 # TARGET_SYS_EXIT_EXTENDED
+
+ # Semihosting call sequence
+ .balign 16
+ slli zero, zero, 0x1f
+ ebreak
+ srai zero, zero, 0x7
+ j .
+
+ .data
+ .balign 16
+semiargs:
+ .space 16
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 31/35] tests: add test with interrupted memory accesses on rv64
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (29 preceding siblings ...)
2025-10-29 15:50 ` [PULL 30/35] tests: add test for double-traps on rv64 Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 32/35] plugins/core: add missing QEMU_DISABLE_CFI annotations Alex Bennée
` (4 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Julian Ganz, Daniel Henrique Barboza, Alex Bennée,
Palmer Dabbelt, Alistair Francis, Weiwei Li, Liu Zhiwei,
open list:RISC-V TCG CPUs
From: Julian Ganz <neither@nut.email>
This test aims at catching API misbehaviour w.r.t. the interaction
between interrupts and memory accesses, such as the bug fixed in
27f347e6a1d269c533633c812321cabb249eada8
(accel/tcg: also suppress asynchronous IRQs for cpu_io_recompile)
Because the condition for triggering misbehaviour may not be
deterministic and the cross-section between memory accesses and
interrupt handlers may be small, we have to place our trust in large
numbers. Instead of guessing/trying an arbitrary, fixed loop-bound, we
decided to loop for a fixed amount of real-time. This avoids the test
running into a time-out on slower machines while enabling a high number
of possible interactions on faster machines.
The test program sends a single '.' per 1000000 loads/stores over the
serial. This output is not captured, but may be used by developers to
gauge the number of possible interactions.
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Signed-off-by: Julian Ganz <neither@nut.email>
Message-ID: <20251027110344.2289945-32-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/tests/tcg/riscv64/Makefile.softmmu-target b/tests/tcg/riscv64/Makefile.softmmu-target
index d9c0036eb4b..eb1ce6504a0 100644
--- a/tests/tcg/riscv64/Makefile.softmmu-target
+++ b/tests/tcg/riscv64/Makefile.softmmu-target
@@ -30,5 +30,11 @@ run-plugin-doubletrap: doubletrap
$(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $<.pout \
$(QEMU_OPTS)$<)
+EXTRA_RUNS += run-plugin-interruptedmemory
+run-plugin-interruptedmemory: interruptedmemory
+ $(call run-test, $<, \
+ $(QEMU) -plugin ../plugins/libdiscons.so -d plugin -D $<.pout \
+ $(QEMU_OPTS)$<)
+
# We don't currently support the multiarch system tests
undefine MULTIARCH_TESTS
diff --git a/tests/tcg/riscv64/interruptedmemory.S b/tests/tcg/riscv64/interruptedmemory.S
new file mode 100644
index 00000000000..cd9073ee314
--- /dev/null
+++ b/tests/tcg/riscv64/interruptedmemory.S
@@ -0,0 +1,97 @@
+ .option norvc
+
+ .text
+ .global _start
+_start:
+ # Set up trap vector
+ lla t0, trap
+ csrw mtvec, t0
+
+ # Set up timer
+ lui t1, 0x02004
+ sd zero, 0(t1) # MTIMECMP0
+
+ # Enable timer interrupts
+ li t0, 0x80
+ csrrs zero, mie, t0
+ csrrsi zero, mstatus, 0x8
+
+ # Set up UART
+ lui t1, 0x10000
+ li a0, 0x80 # DLAB=1
+ sb a0, 3(t1)
+ li a0, 1 # Full speed
+ sw a0, 0(t1)
+ li a0, 0x03 # 8N1, DLAB=0
+ sb a0, 3(t1)
+
+ # Run test for around 60s
+ call rtc_get
+ li t0, 30
+ slli t0, t0, 30 # Approx. 10e9 ns
+ add t0, t0, a0
+0:
+ # Tight loop with memory accesses
+ li a1, 1000000
+ la a2, semiargs
+1:
+ ld a0, 0(a2)
+ sd a0, 0(a2)
+ addi a1, a1, -1
+ bnez a1, 1b
+
+ li a0, '.'
+ call send_byte
+ call rtc_get
+ bltu a0, t0, 0b
+
+ li a0, '\n'
+ call send_byte
+
+ # Exit
+ li a0, 0
+ lla a1, semiargs
+ li t0, 0x20026 # ADP_Stopped_ApplicationExit
+ sd t0, 0(a1)
+ sd a0, 8(a1)
+ li a0, 0x20 # TARGET_SYS_EXIT_EXTENDED
+
+ # Semihosting call sequence
+ .balign 16
+ slli zero, zero, 0x1f
+ ebreak
+ srai zero, zero, 0x7
+
+ j .
+
+rtc_get:
+ # Get current time from the goldfish RTC
+ lui t3, 0x0101
+ lw a0, 0(t3)
+ lw t3, 4(t3)
+ slli t3, t3, 32
+ add a0, a0, t3
+ ret
+
+send_byte:
+ # Send a single byte over the serial
+ lui t3, 0x10000
+ lb a1, 5(t3)
+ andi a1, a1, 0x20
+ beqz a1, send_byte
+ sb a0, 0(t3)
+ ret
+
+ .balign 4
+trap:
+ lui t5, 0x0200c
+ ld t6, -0x8(t5) # MTIME
+ addi t6, t6, 100
+ lui t5, 0x02004
+ sd t6, 0(t5) # MTIMECMP
+ mret
+
+ .data
+ .balign 16
+semiargs:
+ .space 16
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 32/35] plugins/core: add missing QEMU_DISABLE_CFI annotations
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (30 preceding siblings ...)
2025-10-29 15:50 ` [PULL 31/35] tests: add test with interrupted memory accesses " Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 33/35] configs: drop SBSA_REF from minimal specification Alex Bennée
` (3 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Bennée, Peter Maydell, Pierrick Bouvier,
Alexandre Iooss, Mahmoud Mandour
Most of the memory callbacks come directly from the generated code
however we have do have a a direct from C callback for the slow-path
and memory helpers.
There is also a reset callback that calls out to plugins.
Like the other plugin points we need to disable CFI as we are making
function calls to dynamically linked libraries.
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3175
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Message-ID: <20251027110344.2289945-33-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/plugins/core.c b/plugins/core.c
index 35a252d2729..8f8bc7219c2 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -668,6 +668,7 @@ void exec_inline_op(enum plugin_dyn_cb_type type,
}
}
+QEMU_DISABLE_CFI
void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
uint64_t value_low,
uint64_t value_high,
diff --git a/plugins/loader.c b/plugins/loader.c
index ba10ebac993..0dbe7bea263 100644
--- a/plugins/loader.c
+++ b/plugins/loader.c
@@ -318,6 +318,7 @@ struct qemu_plugin_reset_data {
bool reset;
};
+QEMU_DISABLE_CFI
static void plugin_reset_destroy__locked(struct qemu_plugin_reset_data *data)
{
struct qemu_plugin_ctx *ctx = data->ctx;
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 33/35] configs: drop SBSA_REF from minimal specification
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (31 preceding siblings ...)
2025-10-29 15:50 ` [PULL 32/35] plugins/core: add missing QEMU_DISABLE_CFI annotations Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 34/35] gdbstub: Fix %s formatting Alex Bennée
` (2 subsequent siblings)
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée, Philippe Mathieu-Daudé, Thomas Huth
The whole point of SBSA_REF is for testing firmware which by
definition requires TCG. This means the configuration of:
--disable-tcg --with-devices-aarch64=minimal
makes no sense (and indeed is broken for the
ubuntu-24.04-aarch64-notcg) test. Drop it from minimal and remove the
allow_failure from the test case.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-34-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/configs/devices/aarch64-softmmu/minimal.mak b/configs/devices/aarch64-softmmu/minimal.mak
index 0ebc1dca561..3c8582e12cc 100644
--- a/configs/devices/aarch64-softmmu/minimal.mak
+++ b/configs/devices/aarch64-softmmu/minimal.mak
@@ -6,4 +6,3 @@
#
CONFIG_ARM_VIRT=y
-CONFIG_SBSA_REF=y
diff --git a/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch64.yml b/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch64.yml
index 46db9ae0138..ee13587d99e 100644
--- a/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch64.yml
+++ b/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch64.yml
@@ -107,7 +107,5 @@ ubuntu-24.04-aarch64-notcg:
rules:
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/'
when: manual
- allow_failure: true
- if: "$AARCH64_RUNNER_AVAILABLE"
when: manual
- allow_failure: true
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 34/35] gdbstub: Fix %s formatting
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (32 preceding siblings ...)
2025-10-29 15:50 ` [PULL 33/35] configs: drop SBSA_REF from minimal specification Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-29 15:50 ` [PULL 35/35] semihosting: Fix GDB File-I/O FLEN Alex Bennée
2025-10-31 9:25 ` [PULL 00/35] maintainer updates (ci, plugins, semihosting) Richard Henderson
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel
Cc: Sean Anderson, Richard Henderson, Alex Bennée,
Philippe Mathieu-Daudé
From: Sean Anderson <sean.anderson@linux.dev>
The format string for %s has two format characters. This causes it to
emit strings like "466f5bd8/6x" instead of "466f5bd8/6". GDB detects
this and returns EIO, causing all open File I/O calls to fail.
Fixes: 0820a075af ("gdbstub: Adjust gdb_do_syscall to only use uint32_t and uint64_t")
Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20251027110344.2289945-35-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/gdbstub/syscalls.c b/gdbstub/syscalls.c
index e855df21aba..d8bb90cc1c7 100644
--- a/gdbstub/syscalls.c
+++ b/gdbstub/syscalls.c
@@ -127,7 +127,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
case 's':
i64 = va_arg(va, uint64_t);
i32 = va_arg(va, uint32_t);
- p += snprintf(p, p_end - p, "%" PRIx64 "/%x" PRIx32, i64, i32);
+ p += snprintf(p, p_end - p, "%" PRIx64 "/%" PRIx32, i64, i32);
break;
default:
bad_format:
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* [PULL 35/35] semihosting: Fix GDB File-I/O FLEN
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (33 preceding siblings ...)
2025-10-29 15:50 ` [PULL 34/35] gdbstub: Fix %s formatting Alex Bennée
@ 2025-10-29 15:50 ` Alex Bennée
2025-10-31 9:25 ` [PULL 00/35] maintainer updates (ci, plugins, semihosting) Richard Henderson
35 siblings, 0 replies; 37+ messages in thread
From: Alex Bennée @ 2025-10-29 15:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Sean Anderson, Alex Bennée
From: Sean Anderson <sean.anderson@linux.dev>
fstat returns 0 on success and -1 on error. Since we have already
checked for error, ret must be zero. Therefore, any call to fstat on a
non-empty file will return -1/EOVERFLOW.
Restore the original logic that just did a byteswap. I don't really know
what the intention of the fixed commit was.
Fixes: a6300ed6b7 ("semihosting: Split out semihost_sys_flen")
Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-ID: <20251027110344.2289945-36-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 61001267965..c5a07cb947b 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -316,10 +316,7 @@ common_semi_flen_fstat_cb(CPUState *cs, uint64_t ret, int err)
&size, 8, 0)) {
ret = -1, err = EFAULT;
} else {
- size = be64_to_cpu(size);
- if (ret != size) {
- ret = -1, err = EOVERFLOW;
- }
+ ret = be64_to_cpu(size);
}
}
common_semi_cb(cs, ret, err);
--
2.47.3
^ permalink raw reply related [flat|nested] 37+ messages in thread* Re: [PULL 00/35] maintainer updates (ci, plugins, semihosting)
2025-10-29 15:50 [PULL 00/35] maintainer updates (ci, plugins, semihosting) Alex Bennée
` (34 preceding siblings ...)
2025-10-29 15:50 ` [PULL 35/35] semihosting: Fix GDB File-I/O FLEN Alex Bennée
@ 2025-10-31 9:25 ` Richard Henderson
35 siblings, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2025-10-31 9:25 UTC (permalink / raw)
To: qemu-devel
On 10/29/25 16:50, Alex Bennée wrote:
> The following changes since commit e090e0312dc9030d94e38e3d98a88718d3561e4e:
>
> Merge tag 'pull-trivial-patches' ofhttps://gitlab.com/mjt0k/qemu into staging (2025-10-29 10:44:15 +0100)
>
> are available in the Git repository at:
>
> https://gitlab.com/stsquad/qemu.git tags/pull-10.2-maintainer-291025-1
>
> for you to fetch changes up to 4f45b2c352bb72c13a8801805061b31979e3f048:
>
> semihosting: Fix GDB File-I/O FLEN (2025-10-29 14:13:40 +0000)
>
> ----------------------------------------------------------------
> maintainer updates for 10.2
>
> - clean-up remaining 32 bit armhf bits in ci
> - rationalise build-environment.yml for Debian and Ubuntu
> - generate a Debian ppc64 package list
> - rationalise gitlab-runner.yml for Debian and Ubuntu
> - new TCG plugin feature to track discontinuities
> - add missing CFI annotation to plugin callbacks
> - drop SBSA_REF from minimal Arm build
> - format string fix for gdbstub syscall response
> - simplify the gdbstub flen handling for semihosting
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/10.2 as appropriate.
r~
^ permalink raw reply [flat|nested] 37+ messages in thread