Richard, do you have any idea how to fix this problem?
Thanks, Laurent Le 12/03/2021 à 12:09, Laurent Vivier a écrit : > Hi, > > On 16/02/2021 17:16, Peter Maydell wrote: >> From: Richard Henderson <richard.hender...@linaro.org> >> >> A proper syndrome is required to fill in the proper si_code. >> Use page_get_flags to determine permission vs translation for user-only. >> >> Reviewed-by: Peter Maydell <peter.mayd...@linaro.org> >> Signed-off-by: Richard Henderson <richard.hender...@linaro.org> >> Message-id: 20210212184902.1251044-27-richard.hender...@linaro.org >> Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> >> --- >> linux-user/aarch64/cpu_loop.c | 24 +++++++++++++++++++++--- >> target/arm/tlb_helper.c | 15 +++++++++------ >> 2 files changed, 30 insertions(+), 9 deletions(-) > > While I was testing my next linux-user pull request I found this patch breaks > something. > > Following LTP tests are broken: > > mmap05 > mprotect02 > mprotect03 > mprotect04 > shmat01 > > with arm64/sid, arm64/trusty, arm64/bionic > > Bisecting only using mmap05 test I find this patch. > > Symptoms are: > > $ sudo unshare --time --ipc --uts --pid --fork --kill-child --mount > --mount-proc --root > chroot/arm64/sid /opt/ltp/testcases/bin/mmap05 > ** > ERROR:../../../Projects/qemu/linux-user/aarch64/cpu_loop.c:141:cpu_loop: code > should not > be reached > Bail out! > ERROR:../../../Projects/qemu/linux-user/aarch64/cpu_loop.c:141:cpu_loop: code > should not be reached > qemu:handle_cpu_signal received signal outside vCPU context @ > pc=0x7f45c1cd9706 > > Expected result is: > > mmap05 1 TPASS : Got SIGSEGV as expected > > Thanks, > Laurent > >> >> diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c >> index 42b9c15f536..4e43906e66a 100644 >> --- a/linux-user/aarch64/cpu_loop.c >> +++ b/linux-user/aarch64/cpu_loop.c >> @@ -23,6 +23,7 @@ >> #include "cpu_loop-common.h" >> #include "qemu/guest-random.h" >> #include "hw/semihosting/common-semi.h" >> +#include "target/arm/syndrome.h" >> >> #define get_user_code_u32(x, gaddr, env) \ >> ({ abi_long __r = get_user_u32((x), (gaddr)); \ >> @@ -76,7 +77,7 @@ >> void cpu_loop(CPUARMState *env) >> { >> CPUState *cs = env_cpu(env); >> - int trapnr; >> + int trapnr, ec, fsc; >> abi_long ret; >> target_siginfo_t info; >> >> @@ -117,9 +118,26 @@ void cpu_loop(CPUARMState *env) >> case EXCP_DATA_ABORT: >> info.si_signo = TARGET_SIGSEGV; >> info.si_errno = 0; >> - /* XXX: check env->error_code */ >> - info.si_code = TARGET_SEGV_MAPERR; >> info._sifields._sigfault._addr = env->exception.vaddress; >> + >> + /* We should only arrive here with EC in {DATAABORT, >> INSNABORT}. */ >> + ec = syn_get_ec(env->exception.syndrome); >> + assert(ec == EC_DATAABORT || ec == EC_INSNABORT); >> + >> + /* Both EC have the same format for FSC, or close enough. */ >> + fsc = extract32(env->exception.syndrome, 0, 6); >> + switch (fsc) { >> + case 0x04 ... 0x07: /* Translation fault, level {0-3} */ >> + info.si_code = TARGET_SEGV_MAPERR; >> + break; >> + case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */ >> + case 0x0d ... 0x0f: /* Permission fault, level {1-3} */ >> + info.si_code = TARGET_SEGV_ACCERR; >> + break; >> + default: >> + g_assert_not_reached(); >> + } >> + >> queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); >> break; >> case EXCP_DEBUG: >> diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c >> index df85079d9f0..9609333cbdf 100644 >> --- a/target/arm/tlb_helper.c >> +++ b/target/arm/tlb_helper.c >> @@ -154,21 +154,24 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int >> size, >> bool probe, uintptr_t retaddr) >> { >> ARMCPU *cpu = ARM_CPU(cs); >> + ARMMMUFaultInfo fi = {}; >> >> #ifdef CONFIG_USER_ONLY >> - cpu->env.exception.vaddress = address; >> - if (access_type == MMU_INST_FETCH) { >> - cs->exception_index = EXCP_PREFETCH_ABORT; >> + int flags = page_get_flags(useronly_clean_ptr(address)); >> + if (flags & PAGE_VALID) { >> + fi.type = ARMFault_Permission; >> } else { >> - cs->exception_index = EXCP_DATA_ABORT; >> + fi.type = ARMFault_Translation; >> } >> - cpu_loop_exit_restore(cs, retaddr); >> + >> + /* now we have a real cpu fault */ >> + cpu_restore_state(cs, retaddr, true); >> + arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi); >> #else >> hwaddr phys_addr; >> target_ulong page_size; >> int prot, ret; >> MemTxAttrs attrs = {}; >> - ARMMMUFaultInfo fi = {}; >> ARMCacheAttrs cacheattrs = {}; >> >> /* >> > >