All current tcg hosts support division, so the helpers
are no longer used.
Reviewed-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Add log_raise_exception(), a common helper cpu_loop_*() can
call to log a raised exception when '-d int' is used, and
qemu_excp_name() to resolve QEMU-internal exceptions to names.
Use it in cpu_loop_exit_atomic() to log the EXCP_ATOMIC reason.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Message-ID: <20261022215115.19680-4-philmd@oss.qualcomm.com>
All remaining users of cpu_exec_halt simply alias cpu_has_work().
Call cpu_has_work() directly from the generic halt flow and remove
the redundant hook registrations and interface definition.
Make affected cpu_has_work() helpers private where possible.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260930174946.82195-9-philmd@oss.qualcomm.com>
Split target-specific halt handling into an optional
poll_during_halt() callback before cpu_has_work() and a
leaving_halt() callback after work is found.
Keep cpu_exec_halt() as a legacy alternative for targets
that have not migrated. Require each target to provide either
cpu_exec_halt() or leaving_halt(), but not both.
Inspired-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260930174946.82195-3-philmd@oss.qualcomm.com>
* target/i386/tcg: fix EFLAGS reads in TCG plugin callbacks
* target/i386/tcg: raise #GP(0) on null SS load with RPL != CPL
* target/i386/tcg: Don't clear C1 for FCOMI/FCOMIP/FUCOMI/FUCOMIP
* target/i386/tcg: implement APX
* target/i386: Migrate error code only with an exception
* agents: Add a skill for finding your way around QEMU
* tdx: fix buffer overflow in tdx_parse_panic_message
* accel/kvm: fixes
# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmrDtEEUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroN54Qf/WWX2G/Jh3WsKI7/9ahX+aqaOsGqP
# hdz8c6VurrGFwD4a6W8M73962XvrSlR0cNixXxjEo5lZ5UEuLXoCNuNHOW7TTHgF
# tGbfmX8hDMsU/VepRXjIVq5CQuJx6GJtYGf0bWROt3FkM3mn9xYevKu6bg9szNEX
# 3P71MtHIH/CMqP6/oI6VdHeGmNhGamiAoSLqly5t303CbtCULZiTZlqf3xMxjvVO
# M+hFMaW44kvXmpKWo8XLkWhcEasBuULJdKgq7cRIIrE1VNM+f9tItaEbxmozxlfT
# ae5+y1M/H5LAwjYLqTgUy2mvCcZ/btcdjU+wrWzYeSuAcOu4IRC1jQ4ozw==
# =d5mw
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 05 Oct 2026 04:29:21 PM CEST
# gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg: issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [unknown]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (32 commits)
agents: Add a skill for finding your way around QEMU
target/i386/tcg: mark APX as supported
target/i386: extract computation of no-autoenable features
target/i386/tcg: optimize CCMP
target/i386/tcg: decode APX instructions
target/i386/tcg: implement CCMP/CTEST
target/i386/tcg: add decode functionality for APX
target/i386/tcg: decode EVEX prefix
target/i386/tcg: extend VEX.vvvv parsing for APX
target/i386/tcg: implement JMPABS instruction
target/i386/tcg: decode REX2 prefix
target/i386/tcg: treat 0x0F as a prefix
target/i386/tcg: mark XSAVE* as not allowing REX2
target/i386/tcg: add definition for REX2 prefix
target/i386/tcg: add APX support to XSAVE/XRSTOR
target/i386/tcg: unify MOVBE and BSWAP generators
target/i386/tcg: use zextT1 for CMPXCHG
target/i386/tcg: use standard operand order for BSF and BSR
target/i386/tcg: generalize zero- and sign-extension
accel/kvm: coalesced mmio: check lenght of the MMIO write entry
...
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Implement software breakpoint based guest debugging for the MSHV
accelerator, modeled on the WHPX backend. The guest-visible debug
registers are not used: a breakpoint is an INT1 (opcode 0xf1)
patched into guest memory, which raises a #DB when executed.
A partition-wide intercept on #DB is installed the first time a
breakpoint (or single step) is requested. The intercept is not uninstalled,
so it stays for the lifetime of the VM and every vmexit mshv_handle_debug()
decides whether the #DB belongs to gdb (it hit one of our INT1 breakpoints) or
to the guest; a guest-owned #DB is handed back through a pending exception
event so the guest takes it through its own IDT.
Guest INT3 (#BP) is deliberately left to the guest's own IDT and is never
intercepted.
(adapted to the signature change of accel_ops->update_guest_debug)
Signed-off-by: Doru Blânzeanu <dblanzeanu@linux.microsoft.com>
Reviewed-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
KVM's coalesced mmio ring buffer has entries that contain deffered MMIO
writes.
Each such entry contains the length, an 8 byte value and a guest address.
While the length value comes from the kernel, it is still possible for
an attacker to corrupt the length field using another exploit.
The attacker can then invoke kvm_flush_coalesced_mmio_buffer, which blindly
trusts the length and can be used to inflict further damage.
Add a sanity check on the length field to prevent this.
This patch was only compile tested.
Reported by: "Labs, STAR" <info@starlabs.sg>
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3863
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Link: https://lore.kernel.org/r/20260923004631.100997-1-mlevitsk@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Legacy PCI INTx interrupts are level triggered and can, in theory, be shared.
Upon receiving such an interrupt, VFIO kernel driver masks it in a generic way,
using INTX_DISABLE bit in the PCI config space.
It then waits for the guest to signal completion (EOI) of the interrupt,
upon which VFIO re-enables the interrupt.
The completion is signaled with another eventfd.
For split irqchip mode, KVM doesn't have a notion of EOI on IOAPIC level.
Instead it signals EOI with a userspace VM exit, KVM_EXIT_IOAPIC_EOI.
Upon receiving this VM exit, Qemu manually signals the above-mentioned eventfd.
The problem that this patch resolves is that QEMU keeps these eventfds in
a linked list without any locking to prevent the list from being corrupted by
concurrent access.
Such use is possible and guest triggerable if the guest rapidly toggles
INTX mode of a VFIO device and at the same time signals EOI with an arbitrary
vector.
Fix this by protecting this list (kvm_resample_fd_list) with a mutex.
This patch was only compile tested.
Reported-by: "Vulnerability Report" <vr@darknavy.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3942
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Link: https://lore.kernel.org/r/20260923004651.101197-1-mlevitsk@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
With the mmap support of guest memfd, KVM allows userspace to create
guest memfd serving as normal non-private memory for X86 DEFAULT VM.
However, KVM doesn't support private memory attribute for X86 DEFAULT
VM.
Make kvm_guest_memfd_supported not rely on KVM_MEMORY_ATTRIBUTE_PRIVATE
and check KVM_MEMORY_ATTRIBUTE_PRIVATE separately when the machine
requires guest_memfd to serve as private memory.
This allows QEMU to create guest memfd with mmap to serve as the memory
backend for X86 DEFAULT VM.
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Reviewed-by: David Hildenbrand <david@kernel.org>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Link: https://lore.kernel.org/r/20260929235109.1398509-2-michael.roth@amd.com
Signed-off-by: Peter Xu <peterx@redhat.com>
There was a complex bug with gUSA wherein:
* decode_gusa calls gen_restart_exclusive
* gen_restart_exclusive generates code that sets TB_FLAG_GUSA_EXCLUSIVE
and generates a call to helper_exclusive
* when the code is executed, TB_FLAG_GUSA_EXCLUSIVE is set
* helper_exclusive calls cpu_loop_exit_atomic, this makes cpu_exec exit
with EXCP_ATOMIC
* we go to cpu_loop, we execute cpu_exec_step_atomic
* suppose that exit request is set, cpu_exec_step_atomic does nothing, it
leaves the CPU in the same state as it was before
* we go back to cpu_loop
* suppose that no signal is delivered, so the gUSA is not rewound
* cpu_loop goes to cpu_exec
* there is one difference - now, TB_FLAG_GUSA_EXCLUSIVE is set and it was
clear before - so cpu_exec will not use the TB that calls
helper_exclusive, it will instead use the TB that performs the atomic
operation (both of these TBs have the same PC, they only differ in flags)
* the TB that performs the atomic operation is executed inside cpu_exec
=> race condition
Fix the bug by managing the "are we in cpu_exec_step_atomic" flag
from cpu_exec_step_atomic itself, rather from the translator.
Cc: qemu-stable@nongnu.org
Fixes: 4bfa602bc2 ("target/sh4: Handle user-space atomics")
Reported-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Helge Deller <deller@gmx.de>
curr_cflags() is called once per TB dispatch, from helper_lookup_tb_ptr()
and from the cpu_exec() loop. It recomputes the same value every time:
uint32_t cflags = cpu->tcg_cflags;
if (unlikely(cpu_single_stepping(cpu))) { ... }
else if (qatomic_read(&one_insn_per_tb)) { ... }
else if (qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) { ... }
That is three loads and three branches on the hottest path in the
interpreter, for state that changes only when gdb enables single-step,
when one-insn-per-tb is toggled, or when the log mask changes.
None of the three has to be sampled at dispatch time. Fold each into
CPUState::tcg_cflags where it changes and curr_cflags() becomes a single
load of a field that TB lookup has to read anyway.
The derived bits -- CF_COUNT_MASK, CF_NO_GOTO_TB, CF_NO_GOTO_PTR and
CF_SINGLE_STEP -- are never set by tcg_cflags_set(), so tcg_update_cflags()
can recompute them in place without disturbing the rest, and conversely
tcg_cflags_set() ORs in its bits without disturbing them.
There are three places to call it:
- tcg_exec_realizefn(), so that a CPU created after the command line has
been parsed starts out with the right value. This covers user-only,
where tcg_cpu_init_cflags() is not reached. linux-user's cpu_copy()
copies tcg_cflags wholesale, so a cloned thread inherits it.
- cpu_single_step(), which changes one CPU. gdb is the only caller that
matters; in system mode it runs with the vCPUs stopped, and in user mode
gdb_continue_partial() can reach a thread that is still running, because
gdb_handlesig() stops only the thread that trapped. That is exactly the
plain cross-thread store to another CPU's CPUState that
cpu->singlestep_flags already was, read back by that CPU through
cpu_single_stepping() in curr_cflags(). This patch changes which field
carries it, not who writes it or how.
- hmp_one_insn_per_tb() and hmp_log(), which change every CPU while the
vCPUs are running, so the update is queued with async_run_on_cpu() and
each CPU writes its own cflags from its own thread. The command line
spellings of those two settings need nothing: they are parsed before
any CPU is realized, so tcg_exec_realizefn() picks them up.
Measured with qemu-alpha running an emulated alpha gcc 16.2.0 compiling
the SQLite 3.45.1 amalgamation (255k lines, -O2) on an x86-64 host, in a
build configured with --enable-lto:
before: 1,646,994,254,249 instructions
after: 1,562,204,796,597 instructions -5.15%
That workload issues 8.4 billion dispatches, so the per-call saving is
small but the aggregate is not. The emulated compiler produces
byte-identical output before and after.
Wall clock does not move: 133.19s to 132.58s, a 0.46% difference against a
run-to-run spread larger than that. The removed work is a few predictable
loads and branches that the host executes largely in parallel with the
surrounding dispatch, so this patch is worth taking for the instruction
count and for what it enables, not for a time saving that can be measured
on its own.
v4: Update the cflags from the HMP handlers for 'log' and 'one-insn-per-tb'
rather than from qemu_set_log_internal() and the accelerator property
setter. Those are the paths that reach a running vCPU, and the monitor
is the only thing that does. Suggested by Richard Henderson.
v4: Queue the per-CPU update with async_run_on_cpu() rather than
async_safe_run_on_cpu(). Halting the other vCPUs buys nothing: the
queued work already runs on the owning CPU's own thread. Suggested by
Alex Bennee, who also asked whether there are cross-vCPU updates of
tcg_cflags at all. With this change the monitor path has none: the
only remaining writer from another thread is cpu_single_step(), above,
which is neither new nor made worse here.
v4: Move the stub to accel/stubs/, which is where the other accelerator
stubs live.
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260901034808.3524945-2-mattst88@gmail.com>
Allow the two pages of translation to be non-contiguous.
As long as the target translator wraps pc properly, this
allows address space wraparound to function correctly.
This avoids an assert on a valid i386 system-mode test case.
Reported-by: Tao Cui <cui.tao@linux.dev>
Reviewed-by: Jim MacArthur <jim.macarthur@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
translator_use_goto_tb() refuses to chain unless the destination is on the
same page as the start of the TB. For guests whose text is much larger than
a page this is expensive: an emulated alpha gcc compiling a 255k line
translation unit takes the indirect dispatch path for 8.4 billion of its
34.2 billion TB exits, and a large share of those are ordinary direct
branches that simply crossed an 8 KiB page boundary.
The restriction was made unconditional by d3a2a1d803 ("accel/tcg:
Introduce translator_use_goto_tb"), whose rationale was:
Various targets avoid the page crossing test for CONFIG_USER_ONLY,
but that is wrong: mmap and mprotect can change page permissions.
That is true, but in user-only builds the invalidation path already covers
it. There are no page tables: every mmap, mprotect and munmap reaches
page_set_flags(), which calls tb_invalidate_phys_range() whenever the flags
actually change, and tb_phys_invalidate() calls tb_jmp_unlink() to reset
incoming jumps. A chained cross-page jump is therefore broken whenever the
destination page's permissions change. This is not true in system mode,
where TBs are keyed by physical address and a page table change invalidates
nothing, so the restriction is kept there.
The rule protects one more thing, which the original rationale does not
mention: it guarantees that execution cannot enter a page without a TB
lookup, and so without check_for_breakpoints(). That is what makes a
breakpoint set after a block was translated take effect, since insertion
deliberately invalidates nothing. A link established before the breakpoint
was set would jump straight over it.
So the chaining is only enabled for a run that can never acquire a
breakpoint. In user-only mode every breakpoint comes from gdb -- BP_CPU is
g_assert_not_reached() there, and the guest cannot ask for one -- and gdb
has to be requested with -g before the first block is translated, even
though with suspend=n it may connect later. gdb_may_set_breakpoints()
reports whether it was, and is fixed for the lifetime of the process.
Add tests/tcg/multiarch/test-xpage-chain.c to cover both hazards directly.
It writes the last instruction of one page and the first of the next, so
that the fall-through between them is a cross-page goto_tb, runs it 200000
times so the chain is established, then checks that mprotect(PROT_NONE)
makes the next call fault, and that different code written into the page
once it is mapped back runs rather than a stale translation.
The two instructions -- set the return value register, and return -- are
all the architecture specific code there is; thirteen architectures supply
them and the rest skip.
The test detects the hazard it is meant to detect: with the
tb_invalidate_phys_range() call in page_set_flags() commented out,
it fails both phases, executing page B after PROT_NONE and returning
the stale result.
Run with -b, the same binary stops once the chain is established and
lets tests/tcg/multiarch/gdbstub/xpage-bp.py set a breakpoint on the
far side of it, which the next call has to stop on.
With gdb_may_set_breakpoints() forced to false so that the chaining
stays on under gdb, that breakpoint is missed and the test fails,
which is what makes it a test of the gate rather than of gdb.
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
[rth: Update for meson test infrastructure]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260901034808.3524945-8-mattst88@gmail.com>
Every translation block stores to cpu->neg.can_do_io twice: false before
the first instruction, true before the last one. Nothing reads it in a
user-only build. There is no memory-mapped I/O in linux-user, and every
reader is in system_ss: cputlb.c, watchpoint.c, icount-common.c and
tcg-accel-ops-icount.c.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260901034808.3524945-4-mattst88@gmail.com>
The getter and setter use visit_type_uint32, not visit_type_int.
Fixes: fe17413247 ("tcg: add "-accel tcg,tb-size" and deprecate "-tb-size"")
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
EXCP_HALTED is defined and documented in "exec/cpu-common.h" as:
#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
Since vCPUs can not be halted in user-mode emulation, guard the
whole block within !CONFIG_USER_ONLY section. No logic changes.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20260819145649.23439-3-philmd@oss.qualcomm.com>
Add #ifdef CONFIG_HMP around all hmp_* function implementations and
their HMP-only helpers across subsystems.
This covers monitor_register_hmp* callers, hmp_info_* handlers, and
HMP-only helper functions like slirp_lookup.
To link succesfully, use empty cmds tables in hmp-cmds.c (to be removed
once meson build-sys is updated with !hmp support later in the series)
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20260828-qemu-no-hmp-v5-41-9227de146347@redhat.com>
* dockerfiles: cleanup, update CentOS 9 container to Python 3.11
* rust: fix issues in bits crate
* rust: replace bilge dependency with bitfield-struct
* rust: update build system for Meson 1.12.0
* serial: fix hot-unplug issue
* target/i386: emulate: simplify flags conversion and storage
* target/i386: tcg: small fixes
* target/i386: mshv: complete migration support
* target/i386: sev: add support for SEV features
* target/i386: whpx: bugfixes
# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmqGq8wUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroPWBwf6A4w91Tr+mxm3fjcbr/KjVqFnX45k
# qG8l8+60WlA+YY4lUUCJHc4CtPPH9hinOKgm8yGjPdbFrpdcJgQPor4IUgIHnTGu
# Bjceu5k6wlqR7DRetF0TD+NWC2BCkTtbmFcivLd5Ua/vqZVP5j+CITP3t7v5AiuG
# +jEHPTqdk/RMhPdsXcFBl+WditIGNz1/R+pxMKGYfOxF9rQ86sSLd/y2cWrAYNnc
# bO5s8vBxxoNNSxt8qt48aU4gGKvBajpvVQy4/6bPoSs1Z9fwCyCWkQleYSBcBAyn
# 3VTRAoift8j/xEgyOtXVdsviIeaUCE4S0aUGso+TMlA+SwEwSi20P917pg==
# =OXwa
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 20 Aug 2026 12:25:00 AM PDT
# gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg: issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [unknown]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (53 commits)
rust: remove bilge crate
rust: pl011: switch from bilge to bitfield-struct
rust: update Cargo dependencies
scripts: remove now dead parts of rustc_args.py
docs: rust: update for new-style build rules
rust: use meson automatic parsing of Cargo.toml
meson: use compiler_target() to get rustc target
rust: switch to autogenerated meson rules
rust: switch to cargo subprojects
rust: update Cargo.lock
rust/bits: Use checked_ilog2() in Binary::format to avoid panic
rust/bits: Align SubAssign behavior with Sub
python, meson: update meson required for Rust to 1.12.0
dockerfiles: update CentOS Stream 9 to Python 3.11, Meson to 1.12
dockerfiles: remove packages required by Avocado
meson: make linker warnings non-fatal on Linux
serial: clear transmit retry callback on unrealize
whpx: i386: inject back db
whpx: i386: work around Hyper-V FP state oddities
whpx: i386: synchronise PAT too
...
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
record_save() assumed that a target reads the bytes of an insn as a
strictly ascending sequence of adjacent chunks, and asserted that each
read begins exactly where the previous one ended.
That assumption no longer holds for riscv. Since f9eaa1542b
("target/riscv: support atomic instruction fetch (Ziccif)"),
decode_opc() loads a full aligned word whenever pc is 4-byte aligned,
even when the insn turns out to be a 2-byte compressed one, so the
record may already hold bytes past the end of the insn being
translated. When such a compressed insn sits at page offset 0xffc,
pc_next becomes 0xffe, which is within MAX_INSN_LEN of the end of the
page, and riscv_tr_translate_insn() probes the next insn to decide
whether it would cross the page boundary. That probe reads at offset
2 while the record already covers [0,4), and the assert fires:
qemu-system-riscv32: accel/tcg/translator.c:395: record_save:
Assertion `offset == db->record_start + db->record_len' failed.
record_save() is only reached when the insn is fetched from MMIO, so
this is visible on boards that execute code from a region created with
memory_region_init_io(), such as an XIP flash window mapped over a
serial flash controller.
Both sides of the collision are correct: the wide fetch is required for
Ziccif atomicity, and the probe is required for correct fault reporting
at a page boundary, per 00c07344fa ("target/riscv: Make translator stop
before the end of a page"). Unlike a86d3352ab ("target/riscv: do not
use translator_ldl in opcode_at"), where a non-translation caller had
no business using translator_ld*, the probe here is a genuine
translation read whose bytes must be recorded.
Relax the invariant instead. Keep requiring that a read neither moves
backwards nor leaves a gap, but let a read overlapping the recorded
range extend it only by the bytes past its end.
Cc: qemu-stable@nongnu.org
Fixes: f9eaa1542b ("target/riscv: support atomic instruction fetch (Ziccif)")
Signed-off-by: Ilya Chichkov <ilya.chichkov.dev@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260814142159.3800744-1-ilya.chichkov.dev@gmail.com>
MSHV's "internal activity state" roughly maps to QEMU's env->mp_state
and cpu->halted states that describe state of APs in a guest.
We don't invoke set_mp_state as part of store_vcpu_state() b/c we would
put all BSP + APs in a RUNNABLE (0) state immediately, breaking SMP boot
Instead we store the mp state as part of the load_cleanup() routine
after a migration.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
Link: https://lore.kernel.org/r/20260710101534.664604-11-magnuskulke@linux.microsoft.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This change implements loading and storing the hyperv lapic state as
part of the load/store routines for a vcpu.
The HyperV LAPIC is similar to the the split-irqchip in KVM. MSHV
currently keeps PIC/IOAPIC emulation in userspace, while LAPIC
interrupt injection is handled through hypercalls.
We introduced dedicated apic infra in hw/i386/mshv to handle the
migration and move lapic related functions from target/i386/mshv
there. References have been the WHPX's whpx-apic implemenation and
the mshv-ioctls crate's get_/set_lapic() impl for the mapping
between MSHV/QEMU lapic state.
We are mapping the lapic state that we receive from the hypervisor to
fields in APICCommonState. Common fields are used where feasible, with
an mshv-specific MshvAPICState object that carries mshv-specific
fields.
We have introduced a guard in pic_irq_request() that will early exit
for the mshv accelerator, because mshv cannot take part in the userland
path for legacy PIC interrupt injection.
The TSC_DEADLINE MSR is also migrated as part of LAPIC migration.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
Reviewed-by: Doru Blânzeanu <dblanzeanu@linux.microsoft.com>
Link: https://lore.kernel.org/r/20260710101534.664604-6-magnuskulke@linux.microsoft.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This is a partition-wide state for which we use a dedicated hw clock
facility, similar to KVM. We have to freeze the time for a partition
before we are allowed to set it. We register a state change handler for
the clock device and a post-load handler for migration state. In the
post-load handler we toggle a flag that will set the reference time
state on next state to "running" on the partition.
We can move the time freeze and reference-time ioctls/hvcalls to the
clock module.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
Reviewed-by: Doru Blânzeanu <dblanzeanu@linux.microsoft.com>
Link: https://lore.kernel.org/r/20260710101534.664604-4-magnuskulke@linux.microsoft.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
page_check_range() may race with pageflags_set_clear() as follows:
T1 T2
------------------------------------- --------------------------------
p = pageflags_find(start, last);
interval_tree_remove(&p->itree, ...);
p->itree.start = last + 1;
if (start < p->itree.start) {
ret = false;
interval_tree_insert(&p->itree, ...);
leading to errors like
fail indirect write 0x72f0a659aff0 (Bad address)
in vma-pthread test. I am able to reliably reproduce this on a machine
with 32 SMT threads as follows in about 25 seconds:
jobs=32; \
seq "$jobs" | \
time -p parallel \
--jobs="$jobs" \
--halt=now,done=1 \
--ungroup \
'
_={};
while ./qemu-s390x tests/tcg/s390x-linux-user/vma-pthread; do
printf .;
done
'
Also wasmtime project reported a similar failure pattern in their CI [1]
with a similar reproducer [2].
There are other races like this. In general, region bounds mutating
underneath the reader are very hard to reason about. So fix this by
preventing mutations and creating copies instead. Use RCU guards in
readers to avoid uses-after-frees.
Now, when the reader finds a node, it may fearlessly access its fields
and be certain that at some point in time the respective region had the
respective bounds and permissions. The downside is slightly more
expensive mprotect(), but complexity reduction is worth it.
Lockless field accesses should probably be wrapped in qatomic_read(),
but this is a pre-existing issue, so do not change it here.
[1] https://github.com/bytecodealliance/wasmtime/issues/10000
[2] https://gist.github.com/alexcrichton/f14f23a892ffb9df2522754572d51b1c
Cc: qemu-stable@nongnu.org
Reported-by: Alex Crichton <alex@alexcrichton.com>
Reported-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Fixes: 67ff2186b0 ("accel/tcg: Use interval tree for user-only page tracking")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260706165445.57418-2-iii@linux.ibm.com>
In 6d03226b42 we set TLB_MMIO to a non-zero value for user-only
so that we could return a non-zero value from probe_* functions
so that we could force callers like Arm SVE vector moves to use
the slow path rather than direct access. All for the sake of
exposing these accesses to plugins.
Back then, TLB_FORCE_SLOW did not exist, so TLB_MMIO seemed like
a reasonable solution. However, user-only doesn't really have
MMIO and this has knock-on effects, like forcing Arm SVE first-fault
vector loads to stop. Better to use TLB_FORCE_SLOW as a more exact
trigger for plugins.
Cc: qemu-stable@nongnu.org
Fixes: 6d03226b42 ("plugins: force slow path when plugins instrument memory ops")
Acked-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260702171057.47998-1-richard.henderson@linaro.org>
Now accelerators hold the 'guest debug supported' information
in their state, accessible by the common code. No need to call
a per-accelerator handler, simply check for the SSTEP_ENABLE
in AccelGdbConfig::sstep_flags.
Remove all AccelOpsClass::supports_guest_debug implementations,
inline gdb_supports_guest_debug() and remove the now unnecessary
KVMState::have_guest_debug field.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260705215729.62196-18-philmd@oss.qualcomm.com>
Hold the per-accelerator AccelGdbConfig in AccelState, set its
single @sstep_flags field in AccelClass::init_machine handlers.
Remove the AccelClass::gdbstub_supported_sstep_flags() getter
and inline the single accel_supported_gdbstub_sstep_flags() call
in gdb_init_gdbserver_state().
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260705215729.62196-15-philmd@oss.qualcomm.com>