diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2021-09-17 17:32:56 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-11-02 07:00:52 -0400 |
commit | 72d2bbf9ff3e1edf5d57b53149eeaa36f19fb891 (patch) | |
tree | 6a99451d40f398e90b2421aec5da2a30c591e4b2 /accel | |
parent | 09e94676ade52708cbece8fd4bd255a25b6ee475 (diff) |
linux-user: Add cpu_loop_exit_sigsegv
This is a new interface to be provided by the os emulator for
raising SIGSEGV on fault. Use the new record_sigsegv target hook.
Reviewed by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'accel')
-rw-r--r-- | accel/tcg/user-exec.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index a0cba61e83..c4f69908e9 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -141,35 +141,38 @@ static int probe_access_internal(CPUArchState *env, target_ulong addr, int fault_size, MMUAccessType access_type, bool nonfault, uintptr_t ra) { - int flags; + int acc_flag; + bool maperr; switch (access_type) { case MMU_DATA_STORE: - flags = PAGE_WRITE; + acc_flag = PAGE_WRITE_ORG; break; case MMU_DATA_LOAD: - flags = PAGE_READ; + acc_flag = PAGE_READ; break; case MMU_INST_FETCH: - flags = PAGE_EXEC; + acc_flag = PAGE_EXEC; break; default: g_assert_not_reached(); } - if (!guest_addr_valid_untagged(addr) || - page_check_range(addr, 1, flags) < 0) { - if (nonfault) { - return TLB_INVALID_MASK; - } else { - CPUState *cpu = env_cpu(env); - CPUClass *cc = CPU_GET_CLASS(cpu); - cc->tcg_ops->tlb_fill(cpu, addr, fault_size, access_type, - MMU_USER_IDX, false, ra); - g_assert_not_reached(); + if (guest_addr_valid_untagged(addr)) { + int page_flags = page_get_flags(addr); + if (page_flags & acc_flag) { + return 0; /* success */ } + maperr = !(page_flags & PAGE_VALID); + } else { + maperr = true; + } + + if (nonfault) { + return TLB_INVALID_MASK; } - return 0; + + cpu_loop_exit_sigsegv(env_cpu(env), addr, access_type, maperr, ra); } int probe_access_flags(CPUArchState *env, target_ulong addr, |