We want to use kvm_print_register_name() in machine.c so
let's export the helper and implement a stub when kvm
is not enabled.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20260304101625.1962633-4-eric.auger@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This removes the need for explicitly allocating cpreg_vmstate arrays.
On post save we simply point to cpreg arrays and set the length
accordingly.
Remove VMSTATE_VARRAY_INT32 for cpreg_vmstate_array_len as now
the array is dynamically allocated.
Also add a trace point on post_load to trace potential mismatch
between the number of incoming cpregs versus current ones.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20260304101625.1962633-3-eric.auger@redhat.com
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Already existing VMSTATE_VARRAY_INT32 requires an array to be
pre-allocated, however there are cases when the size is not known in
advance and there is no real need to enforce it.
Introduce VMSTATE_VARRAY_INT32_ALLOC as we currently have for UINT32
and UINT16.
The first user of this variant will be the target/arm/machine.c cpreg
indexes/values arrays.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Xu <peterx@redhat.com>
Message-id: 20260304101625.1962633-2-eric.auger@redhat.com
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
The smc91c111 data frame format in memory (figure 8-1 in the
datasheet) includes a "byte count" field which is intended to be the
total size of the data frame, including not just the packet data but
also the leading and trailing information like the status word and
the byte count field itself. It is therefore possible for the guest
to set this to a value so small that the leading and trailing fields
won't fit and the packet has effectively a negative area.
We weren't checking for this, with the result that when we subtract 6
from the length to get the length of the packet proper we end up with
a negative length, which is then inconsistently handled in the
qemu_send_packet() code such that we can try to transmit a very large
amount of data and read off the end of the device's data array.
Treat excessively small length values the same way we do excessively
large values. As with the oversized case, the datasheet does not
describe what happens for this software error case, and there is no
relevant tx error condition for this, so we just log and drop the
packet.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3304
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20260226175549.1319476-1-peter.maydell@linaro.org
Allow the qtest input to include comment lines, which start with '#'.
This allows writing an input file for qtest which includes commentary,
like this:
# set up TCR in bank 0
write 0x1001000e 2 0
# TCR TXEN
write 0x10010000 2 1
which can make hand-writing or annotating reproduce cases a bit
more convenient.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20260226175700.1319767-1-peter.maydell@linaro.org
Switch to bull.com email address following a company split.
The previous eviden.com address will remain active for a few months.
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@bull.com>
Message-id: 20260302143403.1778326-1-clement.mathieu--drif@bull.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
I am no longer actively involved in the Xen Project.
Signed-off-by: Paul Durrant <pdurrant@amazon.com>
Message-id: 20260224112215.83355-1-paul@xen.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Install an event handler on the vEVENTQ fd to read and propagate host
generated vIOMMU events to the guest.
The handler runs in QEMU's main loop, using a non-blocking fd registered
via qemu_set_fd_handler().
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
Message-id: 20260226084456.112142-6-skolothumtho@nvidia.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Factor out the code that propagates event records to the guest into a
helper function. The accelerated SMMUv3 path can use this to propagate
host events in a subsequent patch.
Take the mutex inside the helper before accessing the Event Queue.
Today event propagation occurs only in the core SMMUv3 path and is
effectively serialized. A subsequent patch will also invoke this helper
from the accelerated event read path, which may run concurrently.
Therefore serialization is required here.
No functional change intended.
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
Message-id: 20260226084456.112142-5-skolothumtho@nvidia.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
When the guest enables the Event Queue and a vIOMMU is present, allocate a
vEVENTQ object so that host-side events related to the vIOMMU can be
received and propagated back to the guest.
Allocate a vEVENTQ only when both of the following conditions are met:
1) The guest SMMUv3 driver has set EVENTQEN = 1 in SMMU_CR0.
2) A vIOMMU exists (created when the first VFIO device is attached).
These two conditions may occur in any order.
In the cold-plug case, the vIOMMU already exists before the guest
driver probes. When the guest sets EVENTQEN = 1 during driver probe,
the vEVENTQ is allocated at that point.
With hot-plug, the VFIO device may be attached either before or after
the guest sets EVENTQEN. If the vIOMMU is created first, allocation is
deferred until EVENTQEN = 1. If EVENTQEN is already set, allocation
happens when the vIOMMU is created.
In all cases, allocation is triggered when the second required
condition becomes true.
Errors from command queue consumption and vEVENTQ allocation are reported
independently as the two operations are unrelated.
Event read and propagation will be added in a later patch.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
Message-id: 20260226084456.112142-4-skolothumtho@nvidia.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Move viommu teardown into a helper function and use it from the
last device removal path.
This groups related cleanup logic in one place and improves readability.
It also makes it easier to extend the teardown in future, for example
when freeing related objects such as vEVENTQ.
No functional change.
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
Message-id: 20260226084456.112142-3-skolothumtho@nvidia.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Add a new helper for IOMMU_VEVENTQ_ALLOC ioctl to allocate a virtual event
queue (vEVENTQ) for a vIOMMU object.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
Message-id: 20260226084456.112142-2-skolothumtho@nvidia.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
The STM32F405 SoC relies on STM32F2xx peripherals (ADC, SPI, TIMER,
USART) and the unimplemented device (UNIMP). However, they are not
selected in Kconfig. This added these dependencies.
Signed-off-by: Chisheng Chen <johnny1001s000602@gmail.com>
Message-id: 20260228070622.2195836-1-johnny1001s000602@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
The xgmac device was only used by the highbank machine that just
has been removed. Being a sysbus device that cannot be instantiated
by the user, this is dead code now and thus can be removed, too.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
These machines have been marked as deprecated two releases ago,
and so far nobody complained that they are still useful, so it's
time to remove these now.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20260226090704.27699-1-thuth@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
All compile time conditionals have no impact at runtime, since they are
representing only possible features for devices present at runtime.
In case they are not present, associated features table will never be
used. In case they are present but some features are not, matching bits
will never be enabled, so those entries will be unused.
Thus, simply expose everything and call it a day.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260225041948.52929-6-philmd@linaro.org
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
PPC architectures use a custom value for VHOST_USER_MAX_RAM_SLOTS (32
instead of 512).
vhost_user struct and several functions use VHOST_USER_MAX_RAM_SLOTS to
define stack allocated buffers. To avoid changing all functions to use
heap allocated buffers, we keep this max, and simply add a
target_base_ppc() conditional for the single place where size really
matters.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260225041948.52929-5-philmd@linaro.org
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Thanks to previous refactoring, we can see more easily it is strictly
equivalent to always call virtio_vdev_is_big_endian.
static inline bool virtio_vdev_is_big_endian(VirtIODevice *vdev)
{
if (virtio_vdev_is_legacy(vdev)) {
assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
}
/* Devices conforming to VIRTIO 1.0 or later are always LE. */
return false;
}
The key is to understand that vdev->device_endian is initialized as
expected. It always contains cpu endianness, and not
device endianness, ignoring if device is legacy or not.
By default, it's initialized to vdev->device_endian =
virtio_default_endian(), which matches target default endianness.
Then, on virtio_reset, it will be initialized with current_cpu
endianness (if there is one current_cpu).
void virtio_reset() {
...
if (current_cpu) {
/* Guest initiated reset */
vdev->device_endian = virtio_current_cpu_endian();
} else {
/* System reset */
vdev->device_endian = virtio_default_endian();
}
Now, we can see how existing virtio_access_is_big_endian is equivalent
to virtio_vdev_is_big_endian. Let's break the existing function in its 3
variants, and compare that to virtio_vdev_is_big_endian.
static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
- #if defined(LEGACY_VIRTIO_IS_BIENDIAN)
return virtio_vdev_is_big_endian(vdev);
This is the exact replacement we did, so equivalent.
- #elif TARGET_BIG_ENDIAN
if (!virtio_vdev_is_legacy(vdev)) {
return false;
}
return true;
we know target_is_big_endian(), so
vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG.
if (virtio_vdev_is_legacy(vdev)) {
return VIRTIO_DEVICE_ENDIAN_BIG == VIRTIO_DEVICE_ENDIAN_BIG;
}
return false;
It's written in opposite style compared to existing code (if legacy vs
if modern), but it's strictly equivalent.
- #else
return false;
we know !target_is_big_endian(), so
vdev->device_endian == VIRTIO_DEVICE_ENDIAN_LITTLE.
if virtio_vdev_is_legacy(vdev) {
return VIRTIO_DEVICE_ENDIAN_LITTLE == VIRTIO_DEVICE_ENDIAN_BIG;
}
return false;
So it always return false, as expected.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260225041948.52929-3-philmd@linaro.org
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
This simplifies code compared to having
virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1) or
!virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1).
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260225041948.52929-2-philmd@linaro.org
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
In patch_hwaddr() we allocate a GByteArray for the data we read back
from the guest; however we forget to free it, and the leak sanitizer
complains:
Direct leak of 40 byte(s) in 1 object(s) allocated from:
#0 0x56c00ad48293 in malloc (/home/pm215/qemu/build/x86-tgt-san/qemu-system-x86_64+0x1a9f293) (BuildId: 62e2a7dbe5ff146b2fa14d26e24e443f1967edd9)
#1 0x7b3e4cc91ac9 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62ac9) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
#2 0x7b3e4cc54c12 in g_array_sized_new (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x25c12) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
#3 0x7b3e44b06b49 in patch_hwaddr /home/pm215/qemu/build/x86-tgt-san/../../tests/tcg/plugins/patch.c:68:29
Indirect leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x56c00ad486b0 in realloc (/home/pm215/qemu/build/x86-tgt-san/qemu-system-x86_64+0x1a9f6b0) (BuildId: 62e2a7dbe5ff146b2fa14d26e24e443f1967edd9)
#1 0x7b3e4cc92819 in g_realloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x63819) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
#2 0x7b3e4cc54b36 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x25b36) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
#3 0x7b3e4cc55276 in g_array_set_size (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x26276) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
#4 0x7b3e4cc55574 in g_byte_array_set_size (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x26574) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
#5 0x56c00be2ccc1 in qemu_plugin_read_memory_hwaddr /home/pm215/qemu/build/x86-tgt-san/../../plugins/api.c:524:5
Mark the variable as g_autoptr(), as we already do in the equivalent
code in patch_vaddr().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260305161531.1774895-4-peter.maydell@linaro.org
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
In plugin_exit() we call g_hash_table_get_values() to get a GList
which we look at to print some information. This code has
multiple issues:
* it names the local variable for the GList "count", which
shadows the "qemu_plugin_scoreboard *count". This isn't
incorrect, but it is unnecessarily confusing
* it doesn't free the list, and the leak sanitizer complains:
Indirect leak of 2328 byte(s) in 97 object(s) allocated from:
#0 0x5589b0b72293 in malloc (/home/pm215/qemu/build/x86-tgt-san/qemu-system-i386+0x1a2f293) (BuildId: 26964cad9e3f81d35fc144d7cc88b53adf6f60c7)
#1 0x78fd8cfa1ac9 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62ac9) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
#2 0x78fd8cf96e4a in g_list_prepend (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x57e4a) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
#3 0x78fd8cf8b318 in g_hash_table_get_values (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4c318) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
#4 0x78fd84d1a90c in plugin_exit /home/pm215/qemu/build/x86-tgt-san/../../tests/tcg/plugins/mem.c:87:25
* in iterating through the list it updates "count", so by the
time we get to the end of the loop we no longer have a pointer
to the head of the list that we could use to free it
* it checks for the list being NULL twice (once in an if()
and once in the for() loop's "while" condition), which is
redundant
* it skips the loop if g_list_next(counts) is NULL, which means
it will wrongly skip the loop if the list has only one entry
Rewrite the iteration code to fix these problems.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260305161531.1774895-3-peter.maydell@linaro.org
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
In commit eb3f69cac6 we removed the dependency of this mem plugin
on the QEMU headers, but in doing that we introduced undefined
behaviour when the plugin accesses unaligned memory. This shows up
if you build with the gcc or clang undefined behaviour sanitizer
(--enable-ubsan) and run 'make check-tcg', in numerous warnings like:
../../tests/tcg/plugins/mem.c:167:27: runtime error: load of misaligned address 0x7f1f300354b1 for type 'uint16_t' (aka 'unsigned short'), which requires 2 byte alignment
0x7f1f300354b1: note: pointer points here
00 00 00 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c
^
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../../tests/tcg/plugins/mem.c:167:27
Fix this by rearranging the data reads and writes to use
memcpy() instead.
Fixes: eb3f69cac6 ("tests/tcg/plugins/mem.c: remove dependency on qemu headers")
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260305161531.1774895-2-peter.maydell@linaro.org
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
The discontinuity and system call filter callbacks were not reflected in
the versioning comments before. The callbacks have been introduced in
aac73d85d2 and
5ed628d1d3, respectively.
Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Link: https://lore.kernel.org/qemu-devel/c4ecefb4-8769-403f-8420-8bce42e43e13@epfl.ch
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
The additional plugin tests register accesses, specifically both for
read-only and read-write registers. Writing to a read-only register is
currently not tested, as this would trigger an assertion and fail the
test.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
Link: https://lore.kernel.org/qemu-devel/20260305-setpc-v5-v7-8-4c3adba52403@epfl.ch
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
The opaque register handle encodes whether a register is read-only in
the lowest bit and prevents writing to the register via the plugin API
in this case.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
Link: https://lore.kernel.org/qemu-devel/20260305-setpc-v5-v7-7-4c3adba52403@epfl.ch
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Some registers should be marked as read-only from a plugin API
perspective, as writing to them via qemu_plugin_write_register has no
effect. This includes the program counter, and we expose this fact to
the plugins with this patch.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
Link: https://lore.kernel.org/qemu-devel/20260305-setpc-v5-v7-6-4c3adba52403@epfl.ch
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
The test plugin intercepts execution in different contexts. Without the
plugin, any of the implemented test functions would trigger an assert
and fail. With the plugin, control flow is redirected to skip the assert
and return cleanly via the qemu_plugin_set_pc() API.
Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260305-setpc-v5-v7-5-4c3adba52403@epfl.ch
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
This patch adds a plugin API function that allows diverting the program
counter during execution. A potential use case for this functionality is
to skip over parts of the code, e.g., by hooking into a specific
instruction and setting the PC to the next instruction in the callback.
Link: https://lists.nongnu.org/archive/html/qemu-devel/2025-08/msg00656.html
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
Link: https://lore.kernel.org/qemu-devel/20260305-setpc-v5-v7-4-4c3adba52403@epfl.ch
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
The syscall emulation code previously wasn't interruptible via
cpu_loop_exit(), as this construct relies on a longjmp target that is not
live anymore in the syscall handling code. Consequently, longjmp() would
operate on a (potentially overwritten) stale jump buffer. This patch adds an additional
setjmp and the necessary handling around it to make longjmp() (and by
proxy cpu_loop_exit() safe to call even within a syscall context.
Reviewed-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
Link: https://lore.kernel.org/qemu-devel/20260305-setpc-v5-v7-3-4c3adba52403@epfl.ch
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
In addition to the flags specifying whether general-purpose registers
are read-write (rw) during a plugin callback, we add an additional flag
explicitly stating whether the PC is writable. This is in preparation of
a patch that allows to explicitly set the PC to divert control flow from
within a plugin callback, which is currently not possible.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
Link: https://lore.kernel.org/qemu-devel/20260305-setpc-v5-v7-2-4c3adba52403@epfl.ch
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Syscall arguments are abi_long in user code, and plugin syscall
interface works with uint64_t only.
According to C integer promotion rules, the value is sign extended
before becoming unsigned, thus setting high bits when only 32-bit lower
ones should have a significant value.
As a result, we need to clamp values we receive from user-code
accordingly.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260305-setpc-v5-v7-1-4c3adba52403@epfl.ch
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
The GETMRL handling logic extracted MSB/LSB bytes from
s->cfg.buf_size using a mask-and-shift expression:
(buf_size & (0xff00 >> (offset * 8))) >>
(8 - (offset * 8))
While functionally correct, the expression is difficult to read
and obscures the intent, which is simply to return a 16-bit value
in MSB-first order.
Replace the mask/shift formula with explicit MSB/LSB extraction:
offset == 0 -> buf_size >> 8
offset == 1 -> buf_size & 0xff
This makes the code clearer and easier to review without altering
behavior or data ordering.
No functional change.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Jithu Joseph <jithu.joseph@oss.qualcomm.com>
Link: https://lore.kernel.org/qemu-devel/20260303013322.1297499-5-jamin_lin@aspeedtech.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
i3c_send_byte() declared num_sent without initializing it before
passing its address to i3c_send().
Although i3c_send_byte() itself ignores num_sent after the call,
i3c_send() forwards it to trace_i3c_send(). If the target send
callback does not set *num_sent, the trace may print an
uninitialized value, leading to misleading or garbage output.
Example concern from review:
trace_i3c_send(*num_sent, num_to_send, ret == 0);
If *num_sent is not written by the callback, this trace can report
an incorrect number of transmitted bytes.
Initialize num_sent to 0 to ensure deterministic and predictable
trace output, even if the callback fails to update it.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Jithu Joseph <jithu.joseph@oss.qualcomm.com>
Link: https://lore.kernel.org/qemu-devel/20260303013322.1297499-4-jamin_lin@aspeedtech.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
mock_i3c_target_tx() did not update *num_sent before returning.
Although some callers may not directly use this value, i3c_send()
passes num_sent to trace_i3c_send(). If the target TX callback does
not initialize *num_sent, the trace output may report an incorrect
or uninitialized value, leading to confusing debugging information.
For example, the following trace was observed:
mock_i3c_target_tx I3C mock target write 0x12
i3c_send I3C send 0/1 bytes, ack=1 (expected 1/1 bytes)
This happens because *num_sent was never set by the TX callback.
Fix this by setting *num_sent in all return paths,
including the IBI magic handling case, to accurately reflect
the number of bytes consumed.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Jithu Joseph <jithu.joseph@oss.qualcomm.com>
Link: https://lore.kernel.org/qemu-devel/20260303013322.1297499-3-jamin_lin@aspeedtech.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
The RX temporary buffer allocation manually aligned the size using:
num + (4 - (num & 0x03))
Replace this with ROUND_UP(num, 4) for better readability and
consistency with common QEMU coding style.
No functional change.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Jithu Joseph <jithu.joseph@oss.qualcomm.com>
Link: https://lore.kernel.org/qemu-devel/20260303013322.1297499-2-jamin_lin@aspeedtech.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
The size of the is_rsvd lookup table in i3c_addr_is_rsvd() is 255 but
should be 256 to cover all possible uint8_t address values and avoid
potential out-of-bounds access.
The array should be static too as it's a constant lookup table.
Reviewed-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Nabih Estefan <nabihestefan@google.com>
Link: https://lore.kernel.org/qemu-devel/20260302193931.382228-1-clg@redhat.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>