Interpreter ELF failures were previously reported and terminated inside load_elf_image(), so LATX callers could not attach the selected runtime context.
Return a success value and optionally propagate Error objects while preserving the existing fatal behavior at unchanged call sites. Release the mmap lock before returning an error. Also centralize the interp_prefix declaration in linux-user/qemu.h and remove KZT-local duplicates.
Factor runtime-prefix eligibility into one path helper and expose the configured candidate path for later diagnostics without changing path() fallback behavior. This commit intentionally does not change user-visible diagnostics.
Signed-off-by: Hanlu Li <heuleehanlu@gmail.com>
Bound final AOT exclusive entry so shutdown cannot wait forever for a
CPU blocked in native code. On timeout, cancel pending waiter state and
skip final AOT without retaining an exclusive context.
Use the timeout only for exit_group, self SIGKILL, and signals that
already selected the default fatal action. Use an explicit exit reason
so ordinary call sites cannot accidentally select the final path.
Tests:
- meson test test-exclusive-timeout --print-errorlogs
Signed-off-by: Wenqiang Wei <weiwenqiang@mail.ustc.edu.cn>
A forked child can inherit util/path.c path-cache mutex while another host thread holds it. That thread does not exist in the child, so the first path lookup before exec waits forever in pthread_mutex_lock and concurrent Java ProcessBuilder launches hang.
Include the cache lock in the linux-user fork barrier. The parent unlocks it after fork; the child reinitializes it before it handles more guest system calls.
Tested with tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/CommandOutputControlTest.java and a 100-process concurrent fork stress harness.
Signed-off-by: liuchaoyi <liuchaoyi@loongson.cn>
The fast jump cache was freed before the exiting CPU was removed from
the global CPU list. Concurrent TB invalidation could still access the
freed cache and cause a SIGSEGV.
Allocate the cache together with an RCU head and defer its release until
after the CPU is unrealized and an RCU grace period has elapsed. Remove
unsafe cache cleanup from exit_group and fatal signal paths, where the
process address space will be reclaimed by the kernel.
This also preserves cache reclamation for workloads that create and
destroy large numbers of threads.
Tested with compiler/unsafe/OpaqueAccesses.java.
Signed-off-by: liuchaoyi <liuchaoyi@loongson.cn>
Support the namespace clone flags used by CEF while preserving RCU
state across fork and raw clone paths.
Evaluate x86 seccomp-BPF filters at guest syscall boundaries and provide
the SIGSYS metadata required by CEF broker traps. Define the stable
SECCOMP_RET_USER_NOTIF value for older UAPI headers while keeping user
notification unsupported.
Signed-off-by: yuerengan <y347812075@163.com>
Motivation: Normalize the SMC reload additions to QEMU coding conventions while preserving their behavior.
Test: Run strict checkpatch and rebuild all affected x86_64-linux-user objects.
Signed-off-by: Hanlu Li <heuleehanlu@gmail.com>
When LATX_SMC equals 6, TBs that trigger frequent self‑modifications are
re‑translated and optimized. In AOT mode, we propagate the optimization
information through the bool_flags field, enabling SMC‑optimized TBs to
be stored in the AOT cache file.
The context switch should return an address that points to the TB.
This address is used with tcg_tb_lookup() to find the last executed TB
after context switch.
In tu mode, those TB that use tu jmp will move the unlink stub (which performs
the context switch) to the end of tu. This machinism makes the tu codes much
more compact by reducing branch and improving codes locality.
The way to obtain the address that points to the TB is using the JIRL
for context switch. But it will not work when the unlink stub is moved.
This patch fix to make sure the unlink stub will get the correct address
that points to the corresponding TB. Instead using JIRL, the PCADDI is used
in the unlink stub and it will be relocated after the unlink stub is moved.
Signed-off-by: NiuGenen <niugenen@qq.com>
Some atomic instructions are translated with ll.d/sc.d to maintain
atomicity. If the ll.d does an unaligned access to a page that has
PAGE_READ but not PAGE_WRITE, the SIGBUT will be trigered first.
However, the lock_interpret() does not check wether the page has
PAGE_WRITE, or PAGE_WRITE_ORG more specifically.
This patch adds the checking of PAGE_WRITE_ORG in lock_interpret().
To generate correct SEGV for guest, the siginfo is modifyed and the
pc in uc context is changed to point to a store inst.
Signed-off-by: NiuGenen <niugenen@qq.com>
This patch fixes an issue where the CPU_LOG_TB_NOCHAIN flag was not
taking effect, and remove CONFIG_LATX_LAZYTB and CONFIG_LATX_LAZYEXITPC
to improve readability.
Signed-off-by: Hanlu Li <heuleehanlu@gmail.com>
unlink jmp
--------------------- TB0 <----------<---------
| | |
| | <--------- LA_PC(error) |
| | |
--------------------- TB1 |
| | |
| | |
| | <--------- LA_PC(right) |
| | |
| | |
| | |
--------------------- jcc >------->------>-----
When the PC of LA lands at the position shown in the diagram,
during the unlinking process, because TB0 is segmented, the end
of this TB cannot be detected, resulting in unlinking failure.
Signed-off-by: yuerengan <yuerengan@loongson.cn>
Currently dying to one of the core_dump_signal()s deadlocks, because
dump_core_and_abort() calls start_exclusive() two times: first via
stop_all_tasks(), and then via preexit_cleanup() ->
qemu_plugin_user_exit().
There are a number of ways to solve this: resume after dumping core;
check cpu_in_exclusive_context() in qemu_plugin_user_exit(); or make
{start,end}_exclusive() recursive. Pick the last option, since it's
the most straightforward one.
Fixes: da91c1920242 ("linux-user: Clean up when exiting due to a signal")
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20230214140829.45392-3-iii@linux.ibm.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
In the code-first SMC strategy, since the guest page is not writable when there
are TB exist on this page, the store write on this page will always triger SEGV.
Then in signal handler, tb invalidation work is performed and the original store
inst is interpreted. However, the overhead of signal is big.
This patch introduce smc_store_helper to avoid SEGV. In the signal handler, the
SMC operation is performed in page_unprotect(). A simple profiling work is done
in page_unprotect to identify those TB that often triger SEGV. These TB will be
retranslated to use smc_store_helper for store operation instead of execute the
store directly, in order to avoid SEGV.
The smc_store_helper does almost the same things that will be done in the SEGV
signal handler but in a more efficient way. For now, only the following x86
instruction will be retranslated using smc_store_helper.
- mov gpr to mem, which generates st.b st.h st.w st.d
- movaps series, which generates vst
- 4 continuous movaps will be translated together
Things can be done later to make the codes pretty
- use inst pattern to identify 4 continuous movaps pattern
- make the threshold that trigers retranslation configurable
Things can be done later to futher optimize
- reduce the context switch overhead for smc_store_helper
- optimize data structure to generate fast path of smc_store_helper in TB
- handle cross-page cases in smc_store_helper
Things can be done to fix potential error
- fix smc_store_helper under aot
- fix if current tb is modified in smc_store_helper
Configure LAT_SMC's bit[2] to enable this strategy
e.g. LAT_SMC=4 will enable smc store helper (with original shadow page)
e.g. LAT_SMC=6 will enable both shared map ans smc store helper
Signed-off-by: NiuGenen <niugenen@qq.com>
In the code-first SMC strategy, only those TB that is truly affected by the store inst will be invalidated,
which means the page could still be unwritable after page unprotect.
With shadow page strategy (LAT_SMC = 1), the original guest space remains prot none and does not change.
The load and store inst are both interpreted in SEGV signal handler.
With shared map strategy (LAT_SMC = 2), the original guest space could be writable after page unprotect
if this guest page contains no TB in code cache.
This patch add a new field in ShadowPageDesc to identify wether this shadow page is shared map. And
the prot of this page could be changed with mprotect if it is a shared map. In page unprotect, if
there are no TB on this page after invalidation, use mprotect to make the guest page writable again.
Signed-off-by: NiuGenen <niugenen@qq.com>
The SMC (self-modify-code) is a tough problem for a binary translator. The
consistency between the guest program's binary codes and the generated host
binary codes should be correctly and efficiently managed.
This commit introduces different SMC strategy to be performed in LAT. Configure
it with an input option latx-smc or environment virable LAT_SMC. The default
value is 0.
On default, the SMC strategy is write-first. The page that have been translated
will be unwritable to capture the following store inst. In the segv handler,
all the TB on this page will be invalidated and make the page writable again.
Then the store inst can execute without triger segv fault.
On input value != 0, the SMC strategy is code-first. The page is also unwritable
after translation. In the segv handler, only the TB that is actually affected
by the store inst will be invalidated. The page can not become writable if there
are other TB on this page. Then the store inst is interpreted using the shadow
page mechanism, which allows the store inst to finish the write operation.
The write-first strategy could lead to a lot of TB being retranslated since it
will invalidate all the TB on one page no matter they are actually modified.
On the other hand, the code-first strategy could lead to a lot of SEGV fault
since the page keeps unwritable if there are TB on it. The balance between
these two overhead is the key to optimize the SMC strategy.
More optimizations could be done later:
- record the TB's guest codes to avoid retranslation if it is not modified
- use shared mmap instead of shadow page to allow read operation
- use shared mmap to truly enable write on those pages without TB
- retranslate the store inst to avoid segv fault and finish the TB-invalidate
work in a fast path with acceptable overhead
- use some kind of bitmap to maintain the dirty state of one page and
let TB check it during its execution
Signed-off-by: NiuGenen <niugenen@qq.com>
Since jmp_target_arg and tu_unlink are in the same union, initializing
tu_unlink with TU_UNLINK_STUB_INVALID may cause some errors. Currently,
the validity of tu_unlink can be determined using use_tu_jmp(), therefore
UNLINK_STUB_INVALID is being removed.
Direct jumps, indirect jumps, and TU jumps won't coexist in one TB. So,
variables used by them can be consolidated into a union.
Signed-off-by: Wenqiang Wei <weiwenqiang@mail.ustc.edu.cn>
This patch fixes issues introduced in commit `2a6cf89bf7`:
1) Uses GCC statement expressions ({}) in the macro implementation to prevent
syntax errors when used in assignment statements.
2) Remove trailing commas after static_assert() declaratiions to avoid syntax
errors (static_assert doesn't remain in compiled code).
Signed-off-by: Hanlu Li <heuleehanlu@gmail.com>
The 'type' field is used to specify the type of the extcontext,
making it easier to manage and access the extcontext data.
Signed-off-by: Qi HU <github@spcsky.com>
This patch resolves multiple compiler warning triggered by recent toolchain
updates and stricter build flags. These include:
- Fixing buffer size issues reported by __builtin_strncpy.
- Avoiding out-of-bounds array access in fixed-size _u32 arrays.
- Moving struct declarations out of function parameter lists to ensure
visibility and compatibility.
- Cleaning up misplaced typedefs and invalid declarations.
Signed-off-by: Hanlu Li <heuleehanlu@gmail.com>
In the function shared_private_interpret(), the base register of the faulting
instruction was overwriting with the shadow page address. If the base
register was not a itemp reg, this could corrupt its value and break
subsequent instructions.
CLOSES#39
Signed-off-by: Hanlu Li <heuleehanlu@gmail.com>
The correct definition for `uc_mcontext` is provided by `/usr/include/loongarch64-linux-gnu/sys/ucontext.h`.
Signed-off-by: Hanlu Li <heuleehanlu@gmail.com>